【问题标题】:Find common substrings between two character variables查找两个字符变量之间的公共子字符串
【发布时间】:2013-04-18 06:14:36
【问题描述】:

我有两个字符变量(对象的名称),我想提取最大的公共子字符串。

a <- c('blahABCfoo', 'blahDEFfoo')
b <- c('XXABC-123', 'XXDEF-123')

我想要以下结果:

[1] "ABC" "DEF"

这些向量作为输入应该给出相同的结果:

a <- c('textABCxx', 'textDEFxx')
b <- c('zzABCblah', 'zzDEFblah')

这些例子具有代表性。字符串包含标识元素,每个向量元素中的其余文本是常见的,但未知。

是否有解决方案,在以下位置之一(按优先顺序):

  1. 基础R

  2. 推荐包

  3. CRAN 上可用的软件包

假设重复的答案不满足这些要求。

【问题讨论】:

标签: r lcs


【解决方案1】:

这是一个 CRAN 包:

library(qualV)

sapply(seq_along(a), function(i)
    paste(LCS(strsplit(a[i], '')[[1]], strsplit(b[i], '')[[1]])$LCS,
          collapse = ""))

【讨论】:

  • (+1) 用于 CRAN 包。我发现这个函数的输入 really 很奇怪。我的意思是,很明显,必须创建所有后缀。为什么要求用户这样做?好消息是他们有自己的 C 语言 LCS 实现。
  • @Arun,是的,我明白你在说什么,我说的是这个包以处理数字向量为中心,这个函数是 LCSequence,这是一个概括的 LCSubstring。如果有人为字符串编写专门的版本当然会很好,但是哦。
  • @ConfusedMan 此链接是否描述了您的问题:stackoverflow.com/q/28261825/1175496 ?您是否期望仅输出 'AR ' 而不是 'AR I'
  • 另外,我认为用strsplit(a[i],'')[[1]] 替换substring(a[i], seq(1, nchar(a[i])), seq(1, nchar(a[i]))) 更容易。起初我只是觉得这更容易阅读。但是 [this site] 建议 strsplit(...)更有效率
  • 最后,只要 LCS 被设计为接受向量,这里是字符串到向量的翻译:function(a,b){ av &lt;- strsplit(a,'')[[1]]; bv &lt;- strsplit(b,'')[[1]]; return(paste(LCS(av,bv)$LCS, collapse='')); }
【解决方案2】:

如果您不介意使用生物导体封装,那么,您可以使用Rlibstree。安装非常简单。

source("http://bioconductor.org/biocLite.R")
biocLite("Rlibstree") 

那么,你可以这样做:

require(Rlibstree)
ll <- list(a,b)
lapply(data.frame(do.call(rbind, ll), stringsAsFactors=FALSE), 
           function(x) getLongestCommonSubstring(x))

# $X1
# [1] "ABC"

# $X2
# [1] "DEF"

附带说明:我不太确定Rlibstree 是使用libstree 0.42 还是libstree 0.43。这两个库都存在于源包中。我记得在使用libstree 0.42perl 中的一个巨大数组上遇到了内存泄漏(因此出现了错误)。请注意。

【讨论】:

    【解决方案3】:

    因为我有太多不想做的事情,所以我改为这样做了:

    Rgames> for(jj in 1:100) {
    + str2<-sample(letters,100,rep=TRUE)
    + str1<-sample(letters,100,rep=TRUE)
    + longs[jj]<-length(lcstring(str1,str2)[[1]])
    + }
    Rgames> table(longs)
    longs
     2  3  4 
    59 39  2
    

    有人愿意对匹配字符串的实际分布进行统计估计吗? (lcstring 只是一个蛮力的家庭滚动函数;输出包含所有最大字符串,这就是为什么我只查看第一个列表元素)

    【讨论】:

      猜你喜欢
      • 2013-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 2016-04-20
      相关资源
      最近更新 更多