【发布时间】:2021-09-12 12:46:08
【问题描述】:
我有一个包含 K 个元素的向量,我需要检查它是否包含 2 个连续元素的精确子集。
假设 K = 6
vec = c(4,4,3,1,2,2)
如何获得一个指标来检查子集 (4,2) 作为连续元素?在本例中应返回 FALSE,而 (3,1) 应返回 TRUE。
【问题讨论】:
我有一个包含 K 个元素的向量,我需要检查它是否包含 2 个连续元素的精确子集。
假设 K = 6
vec = c(4,4,3,1,2,2)
如何获得一个指标来检查子集 (4,2) 作为连续元素?在本例中应返回 FALSE,而 (3,1) 应返回 TRUE。
【问题讨论】:
另一种方法可能是:
grepl("42", paste(vec, collapse = ""))
[1] FALSE
grepl("31", paste(vec, collapse = ""))
[1] TRUE
【讨论】:
1) 使用具有相同功能的rollapply。
library(zoo)
vec <- c(4,4,3,1,2,2)
x <- c(4, 2)
any(rollapply(vec, length(x), identical, x))
## [1] FALSE
x <- c(3, 1)
any(rollapply(vec, length(x), identical, x))
## [1] TRUE
2) 用 vec 和 x 创建字符串并使用 grepl:
x <- c(4, 2)
grepl(sprintf("\\b%s\\b", toString(x)), toString(vec))
## [1] FALSE
x <- c(3, 1)
grepl(sprintf("\\b%s\\b", toString(x)), toString(vec))
## [1] TRUE
3) 如果 x 总是有两个元素,那么:
x <- c(4, 2)
any(head(vec, -1) == x[1] & tail(vec, -1) == x[2])
## [1] FALSE
x <- c(3, 1)
any(head(vec, -1) == x[1] & tail(vec, -1) == x[2])
## [1] TRUE
【讨论】:
特别是如果您要检查的元素超过 2 个,这可能是值得的:
vec <-= c(4,4,3,1,2,2)
chk <- c(3, 1)
as.logical(length(Reduce(intersect, lapply(seq_along(chk), function(x) which(chk[x] == lead(vec, x - 1))))))
# [1] TRUE
chk <- c(4, 1)
as.logical(length(Reduce(intersect, lapply(seq_along(chk), function(x) which(chk[x] == lead(vec, x - 1))))))
# [1] FALSE
【讨论】:
使用基础 R:
find_subsequence = function (vec, needle) {
sub_idx = seq_along(needle) - 1L
Filter(
function (i) all(needle == vec[sub_idx + i]),
seq_len(length(vec) - length(needle) + 1L)
)
}
find_subsequence(vec, c(3, 1))
# [1] 4
find_subsequence(vec, c(4, 2))
# integer(0)
【讨论】: