【问题标题】:How to check if a string is a cyclic rotation of another?如何检查一个字符串是否是另一个字符串的循环旋转?
【发布时间】:2017-04-30 11:33:11
【问题描述】:

如何检查给定字符串是否是 R 中另一个给定字符串的循环旋转?例如:12343412 循环旋转两次。但我想检查一个字符串是否循环等效于另一个字符串,通过任意数量的移位。

【问题讨论】:

  • 不确定它有多强大,但您可以尝试复制每个向量和 grepl 另一个,或者 -- grepl(y, strrep(x, 2)) || grepl(x, strrep(y, 2))
  • @alexis_laz 不错!检查nchar 是否足以满足您的第一个建议? nchar(x) == nchar(y) & grepl(pattern = y, x = strrep(x, 2))。愿意发布答案吗?

标签: r string cyclic


【解决方案1】:

根据 Henrik 的评论,测试 (i) nchar 相等性和 (ii) 在复制第二个向量后,一个向量是否是另一个向量的一部分,似乎就足够了:

ff = function(x, y) (nchar(y) == nchar(x)) && (grepl(y, strrep(x, 2), fixed = TRUE))

ff("3412", "1234")
#[1] TRUE

【讨论】:

  • 这很好!复制字符串是关键,让正则表达式引擎完成所有工作。比自己创建所有可能的循环旋转要好得多。
  • @UweBlock :我认为这里的主要缺点是,如果“x”非常大并且strrep 无法分配所需的内存
  • 可用内存可能不是第一个达到的限制。 ?"Memory-limits" 表示 字符串中的字节数限制为 2^31 - 1 ~ 2*10^9。因此,如果 y 具有最大长度,则 x 只能有一半字节。总的来说,xy 最多可能有 3*10^9 字节,大致相当于 3 GB 的内存。也许,unicode 可能需要更多内存,但可用内存可能不是您的方法的阻碍。
【解决方案2】:

您可以只生成连续的旋转,直到找到匹配项。如果没有一个旋转匹配,则字符串不是彼此的循环旋转。使用sub的解决方案:

cycrotT = function(s1,s2) {
  if (nchar(s1)!=nchar(s2)) {
    return(FALSE) }
  for (i in 1:nchar(s2)) {
    if (s1==s2) {
      return(TRUE) }
    # Move the first character to the end of the string
    s2 = sub('(.)(.*)', '\\2\\1', s2)
  }
  return(FALSE)
}


> cycrotT("1234567", "1324567")
# [1] FALSE
> cycrotT("1234567", "4567123")
# [1] TRUE
> cycrotT("1234567", "1234568")
# [1] FALSE

【讨论】:

  • 到目前为止似乎通过了所有测试,但受困于仅代码。加入解释,这将是值得投票的。
【解决方案3】:

更长但或许更清晰的方法图:

cyclic_index <- function(string1, string2) {

  ## gather info about the first string
  chars <- el(strsplit(string1, ""))
  length <- length(chars)
  vec <- seq_len(length)

  ## create a matrix of possible permutations
  permutations <- data.frame(matrix(NA, nrow = length, ncol = length + 1))
  names(permutations) <- c("id", paste0("index", vec))

  permutations$id <- vec

  ## calculate the offset indices
  for (r in vec)
    permutations[r, vec + 1] <- (vec + r - 1) %% (length)

  ## a %% a = 0 so reset this to a
  permutations[permutations == 0] <- length

  ## change from indices to characters
  permutations[ , vec + 1] <- sapply(vec, function(x) chars[unlist(permutations[x, vec + 1])])

  ## paste the characters back into strings
  permutations$string <- sapply(vec, function(x) paste0(permutations[x , vec + 1], collapse = ''))

  ## if string2 is a permutation of string1, return TRUE
  return(string2 %in% permutations$string)

}

cyclic_index("jonocarroll", "carrolljono")
#> TRUE

cyclic_index("jonocarroll", "callorrjono")
#> FALSE

cyclic_index("1234567", "4567123")
#> TRUE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-12
    • 2010-10-13
    • 2022-03-31
    • 2019-05-11
    • 2011-02-02
    相关资源
    最近更新 更多