【问题标题】:R - Longest common substringR - 最长公共子串
【发布时间】:2010-11-28 14:32:15
【问题描述】:

有人知道解决the longest common substring problem 的R 包吗?我正在寻找可以在向量上快速工作的东西。

【问题讨论】:

    标签: r string substring longest-substring


    【解决方案1】:

    【讨论】:

    • 你能发布比较'hello world''hella old'结果的示例代码吗?它会产生'hell' 还是'hell old'
    • 第一个链接坏了
    【解决方案2】:

    您应该查看qualV 包的LCS 函数。它是 C 实现的,因此非常高效。

    【讨论】:

    • 注意:该函数将找到最长的公共子序列(在序列的数学意义上),而不是子字符串。因此,例如它将忽略字符串中间的字符以查找它们之间的匹配项。更多详情请看这里:stackoverflow.com/questions/28261825/…
    【解决方案3】:

    这里的问题对于最长公共子串问题的解决方案的预期应用并不完全清楚。我遇到的一个常见应用是在不同数据集中的名称之间进行匹配。 stringdist 包有一个有用的函数amatch(),我觉得它适合这个任务。

    简而言之amatch() 将输入两个向量,第一个是 x 您要从中查找匹配的字符串向量(也可以是单个字符串) ,第二个是table,这是您要比较的字符串向量,并选择与最长公共子字符串的匹配项。然后amatch() 将返回一个长度等于x 的向量 - 此结果的每个元素将是table 中包含最佳匹配的索引。

    详细信息amatch() 采用 method 参数,如果您想匹配最长的公共子字符串,则将其指定为 lcs。对于不同的字符串匹配技术(例如 Levenshtein 距离),还有许多其他选项。还有一个强制性的maxDist 参数。如果table 中的所有字符串与x 中的给定字符串的“距离”更大,那么amatch() 将为其输出的那个元素返回NA。根据您选择的字符串匹配算法,“距离”的定义不同。对于 lcs,它(或多或少)只是意味着有多少不同的(不匹配的)字符。有关详细信息,请参阅文档。

    并行化amatch() 的另一个不错的功能是它会自动为您并行化操作,对要使用的系统资源做出合理的猜测。如果您想对此进行更多控制,可以切换 nthread 参数。

    示例应用

    library(stringdist)
    
    Names1 = c(
    "SILVER EAGLE REFINING, INC. (SW)",
    "ANTELOPE REFINING",
    "ANTELOPE REFINING (DOUGLAS FACILITY)"
    )
    
    Names2 = c(
    "Mobile Concrete, Inc.",
    "Antelope Refining, LLC. ",
    "Silver Eagle Refining Inc."
    )
    
    Match_Idx = amatch(tolower(Names1), tolower(Names2), method = 'lcs', maxDist = Inf)
    Match_Idx
    # [1] 3 2 2
    
    Matches = data.frame(Names1, Names2[Match_Idx])
    Matches
    
    #                                 Names1          Names2.Match_Idx.
    # 1     silver eagle refining, inc. (sw) silver eagle refining inc.
    # 2                    antelope refining   antelope refining, llc. 
    # 3 antelope refining (douglas facility)   antelope refining, llc. 
    
    ### Compare Matches:
    
    Matches$Distance = stringdist(Matches$Names1, Matches$Match, method = 'lcs')
    

    此外,与qualV 中的LCS 等函数不同,这不会考虑涉及忽略中间字符以形成匹配的“子序列”匹配(如here 所述)。例如,看这个:

    Names1 = c(
    "hello"
    )
    
    Names2 = c(
    "hel123l5678o",
    "hell"
    )
    
    Match_Idx = amatch(tolower(Names1), tolower(Names2), method = 'lcs', maxDist = Inf)
    
    Matches = data.frame(Names1, Match = Names2[Match_Idx])
    Matches
    
    # 1  hello  hell
    

    【讨论】:

      【解决方案4】:

      我不懂R,但我曾经实现过Hirschberg算法,速度快,不占用太多空间。

      我记得只有 2 或 3 个递归调用的短函数。

      这是一个链接: http://wordaligned.org/articles/longest-common-subsequence

      所以不要犹豫在 R 中实现它,因为它是一个非常有趣的算法,所以值得付出努力。

      【讨论】:

      猜你喜欢
      • 2014-04-14
      • 2016-06-03
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多