如何无循环生成自复制且排除末尾元素的序列?
无需循环生成自复制且逐次排除末尾元素的序列
针对你需要生成的序列(以4:1为例,输出4 3 2 1 4 3 2 4 3 4),这里提供几种无需显式循环(for/while)的R实现方法:
方法1:用lapply+head快速实现
这是最直观的写法,借助lapply处理每个长度的前缀,再拼接成向量:
fun <- function(x) { unlist(lapply(length(x):1, function(k) head(x, k))) } # 测试 fun(4:1) # [1] 4 3 2 1 4 3 2 4 3 4
逻辑很简单:从原序列的完整长度开始,依次取前k个元素(k从长度值递减到1),最后用unlist把所有子序列合并成一个向量。
方法2:完全向量化实现(无任何循环)
通过构造逻辑矩阵生成索引,完全用向量化操作完成:
fun <- function(x) { n <- length(x) # 生成标记哪些元素需要保留的逻辑矩阵 idx_matrix <- outer(1:n, 1:n, ">=") # 转置后提取所有TRUE对应的原序列元素 x[which(t(idx_matrix))] } # 测试 fun(4:1) # [1] 4 3 2 1 4 3 2 4 3 4
outer(1:n,1:n,">=")生成n×n的矩阵,其中第i行第j列的TRUE表示第i个前缀序列包含原序列的第j个元素。- 转置矩阵后用
which提取所有TRUE的位置,这些位置对应的原序列元素就是最终结果。
方法3:用rep构造重复次数实现
先计算每个元素在最终序列中出现的次数,再用rep生成索引序列:
fun <- function(x) { n <- length(x) # 每个前缀的长度:4,3,2,1 prefix_lengths <- n:1 # 计算每个原元素的重复次数:4出现4次,3出现3次,以此类推 repeat_counts <- rev(cumsum(rev(prefix_lengths))) # 根据重复次数提取元素 x[rep(1:n, repeat_counts)] } # 测试 fun(4:1) # [1] 4 3 2 1 4 3 2 4 3 4
核心是算出每个元素的重复次数:原序列第1个元素会出现在所有前缀里(共4次),第2个元素出现在前3个前缀里(共3次),以此类推,最后用rep生成索引并提取元素。
内容的提问来源于stack exchange,提问作者Deeproad
相关产品推荐
相关产品推荐

