reps <- function(s, n) paste(rep(s, n), collapse = "") # repeat s n times
find.string <- function(string, th = 3, len = floor(nchar(string)/th)) {
for(sublen in len:1)
{
for(inlen in 0:sublen)
{
pat <- paste0("((.{", sublen-inlen, "})(.)(.{", inlen, "}))", reps("(\\2.\\4)", th-1))
r <- regexpr(pat, string, perl = TRUE)
if (attr(r, "capture.length")[1] > 0)
{
if (r > 0)
{
substring(string, r, r + attr(r, "capture.length")[1] - 1)
}
}
}
}
}
为什么这段代码不起作用?基本上,此代码将接受输入字符串110111111
并输出仅满足一个约束的所有模式:
连续出现至少3次。
然而,除此之外,它还将输出具有1个字符的抖动的模式,即类似110
的模式,因为它除了在最后位置之外连续三次出现。但是,这只是输出NULL
。另一个例子可以是:a0cc0vaaaabaaadbaaabbaa00bvw
。此处,其中一个输出为aaaab
。
编辑:输入可以是包含字符或数字的字符串。此外,匹配的最小长度应至少为2.并且是,匹配重叠。此外,输入的格式为:
find.string("a0cc0vaaaabaaadbaaabbaa00bvw")` or `find.string("110111111")
答案 0 :(得分:1)
我没有深入研究你的函数的逻辑,但有一个明显的原因,它有时会返回NULL
。如果您没有明确使用return
函数,R函数将返回它们评估的最后一个表达式。
当sublen
等于1
(外循环)而inlen
等于sublen
(内循环)时会发生这种情况。如果attr(r, "capture.length")[1] > 0
和r > 0
,则返回的值为substring(string, r, r + attr(r, "capture.length")[1] - 1)
。如果不满足其中一个条件,则if
函数返回NULL
,因此find.strings
返回NULL
。
您可以通过一个更简单的示例了解其工作原理:
f <- function() if(FALSE) 1
print(f())
## NULL
您需要将每个循环的结果存储在变量中,然后返回。
其他一些明显的代码改进:
您可以使用逻辑和将if
语句组合在一起。
if (attr(r, "capture.length")[1] > 0 && r > 0)
regexpr
是矢量化的,因此您可以摆脱内部循环,并加快代码速度。