【问题标题】:Count the occurrence of all possible substrings and their occurrence计算所有可能子串的出现次数及其出现次数
【发布时间】:2016-09-07 05:44:51
【问题描述】:

给定一个字符串,我想计算每个可能出现在字符串中的子字符串。例如,给定一个字符串

str = "abab"

我想计算所有可能的子字符串及其值:

"A" = 2
"B" = 2
"AA" = 0
"AB" = 2
"BA" = 1
"BB" = 0

我写了一个函数如下:

countSubstrings <- function(string_try ="", items = NULL )
{
  string_try <- toupper(string_try)

  if(is.null(items))
  {
    items <- strsplit(string_try, "")[[1]]
  }

  n <- length(unique(items))

  counts_substrings <- c()
  substrings_all <- c()

  for (i in 1:n) # Number of characters in substring
  {
    substrings_combo <- gtools::permutations(n, i, unique(items), repeats=TRUE)

    print(paste("The number of combinations is: ", 
          nrow(substrings_combo), "for substrings of length", i))

    for(j in 1:nrow(substrings_combo))
    {
      tosearch <- paste(substrings_combo[j,], collapse = "")

      substrings_all <- c(substrings_all, tosearch)

      total <- sum(grepl(tosearch, 
                 sapply(1:(nchar(string_try) - 1), 
                        function(ii) substr(string_try, ii, ii + 1)))) 

      counts_substrings <- c(counts_substrings, find_overlaps(tosearch, string_try))

    }
  }

  return(list(substrings_all,counts_substrings))
}

它可以满足我的要求,但速度非常慢。我看到一个潜在的缺陷,即使“aa”的出现为零,我的程序也会考虑子字符串“aaa”。这在序列分析和模式挖掘中很流行。我想知道是否已经有更快的实现或者可以以某种方式进行优化。需要一个 R 解决方案。

【问题讨论】:

    标签: r string frequency


    【解决方案1】:

    所有连续的子串?您的示例有一些 0 的值,它们本身不是子字符串。

    怎么样:

    创建一个提取 (not just unique) 长度为 n 的子字符串的函数

    allsubstr <- function(x, n) substring(x, 1:(nchar(x) - n + 1), n:nchar(x))
    

    这可以提取任意一组 1、2、3、...、n 个子字符串

    allsubstr("abab", 1)
    #> [1] "a" "b" "a" "b"
    allsubstr("abab", 2)
    #> [1] "ab" "ba" "ab"
    allsubstr("abab", 3)
    #> [1] "aba" "bab"
    allsubstr("abab", 4)
    #> [1] "abab"
    

    然后这可以迭代 1 直到所需字符串的长度,并创建一个出现的表

    substrings_table <- function(string) table(unlist(sapply(1:nchar(string), allsubstr, x=string)))
    
    substrings_table("abab")
    #>  a   ab  aba abab    b   ba  bab 
    #>  2    2    1    1    2    1    1 
    

    包含所有其他可能的字符组合是对此的潜在扩展,只需对照此表检查组合列表。

    【讨论】:

      【解决方案2】:

      我发现quanteda 包对于这些类型的操作非常有用,

      library(quanteda)
      x <- "abab" 
      
      ngrams(strsplit(x, '')[[1]], n = 2, concatenator = '')
      #[1] "ab" "ba" "ab"
      
      #or
      table(ngrams(strsplit(x, '')[[1]], n = 2, concatenator = ''))
      #ab ba 
      # 2  1 
      
      #or to get all combinations,
      unlist(sapply(1:nchar(x), function(i)table(ngrams(strsplit(x, '')[[1]], n = i, concatenator = ''))))
      #a    b   ab   ba  aba  bab abab 
      #2    2    2    1    1    1    1 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多