【问题标题】:Algorithm to replace matched patterns in string替换字符串中匹配模式的算法
【发布时间】:2014-08-20 12:00:16
【问题描述】:

在字符串上实现查找/替换算法的简单方法是什么?我想使用定义替换规则的字典来转换字符串。问题是每次替换后,我必须确保后续替换对原始字符串进行操作。例如:

我的字符串是:ABCABCDEFDEF

我的规则是:ABC -> DEF 和 DEF -> XXX

所以我的结果应该是:DEFDEFXXXXXX 而不是 XXXXXXXXXXXX(如果我先应用规则一,然后应用规则二,这将是结果)。

【问题讨论】:

  • 对于每个规则,找到与文本匹配的索引。然后应用规则? (我认为一定有更快的方法)
  • 好吧,在我应用每条规则之后,我的索引都会改变,不是吗?
  • 遍历整个字符串一次,将所需子字符串的出现记录在一个列表或类似的数据结构中。然后遍历列表并继续替换!
  • 创建一个有限状态机。这可以手动完成(只需要 5 个状态)或使用生成器(例如 (f)lex)。

标签: string algorithm string-matching


【解决方案1】:

简单的方法:

  • 从第一个字符开始,尝试每个键(如果它出现在该位置)。

  • 如果找到匹配项,替换并继续替换后的字符

  • 否则,从下一个字符继续

记住:

  • 歧义:如果您同时将“AB”和“ABC”作为键,则需要决定哪个应该匹配“ABCD”。通常你希望更长的字符串匹配(否则,它永远不会匹配)

  • Unicode:首先规范化键和原始字符串。

这对于一把钥匙来说当然足够了。但是,它是 O(N*M),其中 N 是字符串长度,M 是替换次数。


改进:

  • 不要线性搜索匹配;而是使用排序的键列表并对原始字符串中的字符进行二进制搜索,然后是下一个等。确实,仅记住在第一遍中找到的匹配项的位置和键并进行替换可能是有益的第二遍

  • 对于有很多替换的大字符串,通常最好构建一个新字符串

  • 使用Aho-Corasick 进行搜索。这利用了有限的搜索空间(即从关键字列表中获得的知识)来避免探测源字符串的每个字符

【讨论】:

    【解决方案2】:

    根据您使用的语言,可能会有预先设计好的功能。如果您使用 C#,String.Replace 可能会有所帮助。这将为您节省很多时间。如果您仍在寻找可以在其他字符串中找到模式的算法,Horspool-algorithm 可能就是您正在寻找的。​​p>

    您仍然需要实现后续替换的逻辑才能对原始字符串进行操作。但这听起来并不难。

    【讨论】:

    • 是的,我可以使用 String.Replace 之类的函数,但我不知道如何独立应用每个规则。
    • 那么您可以保存已更改的子字符串的索引。下次您遍历字符串以查找另一个模式时,您可以查找子字符串是否已更改。
    猜你喜欢
    • 2014-03-22
    • 2014-03-17
    • 2014-09-03
    • 1970-01-01
    • 2020-02-15
    • 2013-10-24
    • 2022-01-02
    • 2016-06-17
    • 2021-01-26
    相关资源
    最近更新 更多