R语言向量模拟栈行为的函数内存错误排查咨询
问题排查与修复:R语言素数筛选函数内存超限问题
问题背景
编写了两个R函数:
find_prime:递归实现素数判断,用于判断一个数是否为素数ls_vec_prime:通过while循环遍历输入向量,将其中素数以**栈方式(前置添加)**存入新向量,但运行时触发「C内存超限」错误
临时修复find_prime处理1的逻辑后,输入vec_1 <- c(1,2,3,4)能得到结果[1] 3 2,但需要彻底排查原错误并规范实现。
原代码错误分析
核心问题:find_prime的无限递归
初始版find_prime未处理a=1的边界情况:
当传入a=1时,初始i=2,满足:
a != i(1≠2)a %% i != 0(1%%2=1≠0)
因此会无限递归调用find_prime(1, i=3)、find_prime(1, i=4)……直到内存耗尽,触发「C内存超限」错误。
临时修复的不足
临时修复中对a=1返回字符串"1 is not Prime",虽能避免无限递归,但返回类型不一致(有时返回逻辑值,有时返回字符串),不符合函数设计的一致性原则,后续判断可能出现隐式类型转换问题。
正确修复方案
1. 完善find_prime的边界处理与递归逻辑
先处理非素数的边界情况(≤1的数直接返回FALSE),同时优化递归终止条件(只需遍历到sqrt(a),减少递归次数):
find_prime <- function(a, i=2){ # 边界处理:≤1的数不是素数 if(a <= 1){ return(FALSE) } # 终止条件:遍历到sqrt(a)还没找到因子,说明是素数 if(i > sqrt(a)){ return(TRUE) } if(a %% i == 0){ return(FALSE) } # 递归调用,i递增 return(find_prime(a, i = i + 1)) }
2. 保留ls_vec_prime的while循环逻辑
原ls_vec_prime的逻辑本身无错误,只需配合修复后的find_prime即可正常运行:
ls_vec_prime <- function(vec){ l <- vector() while(length(vec) != 0){ current <- vec[1] if(find_prime(current)){ # 栈方式前置添加 l <- c(current, l) } # 移除向量第一个元素,继续循环 vec <- vec[-1] } return(l) }
测试验证
vec_1 <- c(1,2,3,4) ls_vec_prime(vec_1) # 输出:[1] 3 2
额外优化建议
向量前置添加c(current, l)每次都会创建新向量,若处理大向量效率较低,可先收集素数再反转(rev()),提升效率:
ls_vec_prime <- function(vec){ l <- vector() while(length(vec) != 0){ current <- vec[1] if(find_prime(current)){ # 先追加到末尾 l <- c(l, current) } vec <- vec[-1] } # 反转实现栈效果 return(rev(l)) }
内容的提问来源于stack exchange,提问作者EnlightenedFunky
相关产品推荐
相关产品推荐

