R语言有限试验次数的优惠券收集问题函数实现求助
问题分析与解决方案
卡顿原因
你的Collectathon2函数卡顿的核心问题有两个:
- 循环条件错误:变量
Trials是数值型变量,length(Trials)永远等于1,当t>1时,length(Trials) < t会一直为TRUE,导致循环无限运行,程序卡死。 - 性能低效:每次循环执行
unique(c(Collected_Coupons, New_Coupon)),随着循环次数增加,向量不断变长,合并+去重的耗时会指数级增长。
修复方案
基础修复版(解决循环卡死问题)
修正循环条件为Trials < t,保留原有逻辑:
Collectathon2 <- function(n, t){ Collected_Coupons <- c() Trials <- 0 while (Trials < t) { New_Coupon <- sample(n, 1) Collected_Coupons <- unique(c(Collected_Coupons, New_Coupon)) Trials <- Trials + 1 } return(length(Collected_Coupons)) }
高性能优化版(解决效率问题)
用逻辑向量记录已收集的优惠券,避免每次合并去重的开销,适合大n和大t的场景:
Collectathon2 <- function(n, t){ # 初始化逻辑向量,标记对应优惠券是否被收集 collected <- logical(n) trials_done <- 0 while (trials_done < t) { new_coupon <- sample(n, 1) collected[new_coupon] <- TRUE trials_done <- trials_done + 1 } # 统计已收集的唯一优惠券数量 return(sum(collected)) }
极简向量化实现
直接生成t次抽样结果,统计唯一值数量,完全避免循环,效率最高:
Collectathon2 <- function(n, t){ length(unique(sample(n, t, replace = TRUE))) }
优化逻辑说明
- 逻辑向量标记方式:每次操作都是O(1)的索引修改,时间复杂度为O(t),远优于原代码的O(t²)。
- 向量化实现:R内置的
sample和unique是底层优化的C代码,比手动循环快得多,尤其当t很大时差距明显。
内容的提问来源于stack exchange,提问作者wec
相关产品推荐
相关产品推荐

