代码之家  ›  专栏  ›  技术社区  ›  VVS

查找文本中所有关键字的有效算法

  •  9
  • VVS  · 技术社区  · 14 年前

    我有很多字符串包含很多不同拼写的文本。我通过搜索关键字来标记这些字符串,如果找到关键字,我将使用该关键字的关联文本。

    假设搜索字符串可以包含文本“schw.”、“schwa.”和“schwarz”。我有三个关键字,所有的解决文本“施瓦兹”。

    现在我正在寻找一种有效的方法来查找所有的关键字,而不必做字符串。每个关键字都包含(keyword)。

    样本数据:

    H-Fuss ahorn 15 cm/SH48cm
    Metall-Fuss chrom 9 cm/SH42cm
    Metall-Kufe alufbg.12 cm/SH45c
    Metall-Kufe verchr.12 cm/SH45c
    Metall-Zylind.aluf.12cm/SH45cm
    Kufe alufarbig
    Metall-Zylinder hoch alufarbig
    Kunststoffgl.schw. - hoch
    Kunststoffgl.schw. - Standard
    Kunststoffgleiter - schwarz für Sitzhoehe 42 cm
    

    示例关键字(键、值):

    h-fuss, Holz
    ahorn, Ahorn
    metall, Metall
    chrom, Chrom
    verchr, Chrom
    alum, Aluminium
    aluf, Aluminium
    kufe, Kufe
    zylind, Zylinder
    hoch, Hoch
    kunststoffgl, Gleiter
    gleiter, Gleiter
    schwarz, Schwarz
    schw., Schwarz
    

    样本结果:

    Holz, Ahorn
    Metall, Chrom
    Metall, Kufe, Aluminium
    Metall, Kufe, Chrom
    Metall, Zylinder, Aluminium
    Kufe, Aluminium
    Metall, Zylinder, Hoch, Aluminium
    Gleiter, Schwarz, Hoch
    Gleiter, Schwarz
    Gleiter, Schwarz
    
    5 回复  |  直到 14 年前
        1
  •  15
  •   The Archetypal Paul    14 年前

    这似乎很合适” Algorithms using finite set of patterns "

    这个 Aho–Corasick string matching 算法是字符串搜索 Alfred V.Aho发明的算法 还有玛格丽特科拉希克。这是一种 字典匹配算法 定位有限集的元素 字符串(“字典”)在 输入文本。它符合所有的模式 “立刻”,所以复杂性 算法的长度是线性的 图案加上 搜索文本加上 输出匹配。请注意,因为 找到匹配项,可能有 如果每 子字符串匹配(例如字典= a、 aa,aaa,aaaa输入字符串是 aaaa)。

    这个 Rabin–Karp algorithm 是一个字符串 Michael创建的搜索算法 O、 1987年拉宾和理查德·M·卡普 使用散列来查找 文本中的一组模式字符串。为了 长度n和p的文本模式 组合长度m,其平均值和 最佳运行时间为O(n+m)in 空间O(p),但它的最坏情况是 O(纳米)。相比之下,阿霍·科拉希克 字符串匹配算法 渐近最坏时间复杂度 空间O(n+m)。

        2
  •  3
  •   jdehaan    14 年前

    我将对每组关键字使用预编译的正则表达式进行匹配。在后台,它们被“编译”成有限自动机,因此它们识别字符串中的模式非常快,并且比 Contains 对于每个可能的字符串。

    使用: System.Text.RegularExpressions .

    在您的示例中:

    • “schw.”、“schwa.”和“schwarz”
    • new Regex(@"schw(a?\.|arz)", RegexOptions.Compiled)

    此处提供更多文档: http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regexoptions(v=VS.90).aspx

        3
  •  1
  •   hmuelner    14 年前

    如果您有一组固定的关键字,可以使用(f)lex, re2c ragel

        4
  •  0
  •   Aliostad    14 年前

    我建议采取以下措施:

    1) 标记使用 string.Split 和你的钥匙字典比对

    2) 使用 ReadToken() 方法,该方法将字符添加到缓冲区中,直到找到(拆分可能正在执行此操作)拆分字符并将其作为令牌输出。然后你对照你的字典。

        5
  •  0
  •   Oliver    14 年前

    也许有点力不从心,但你一定要看看 ANTLR .