假设您有一个函数,它接受一个数字作为输入并输出一个向量。但是,输出向量的大小取决于输入,并且您无法在函数之前计算它。
例如,采取3N+1著名算法 https://en.wikipedia.org/wiki/Collatz_conjecture。该算法的一个简单实现,返回 1 之前的整个路径,如下所示:
compute <- function(x) {
if (x %% 2 == 0)
return(x / 2)
return(3*x + 1)
}
algo <- function(x) {
if (x == 1)
return(1)
output <- x
while(x != 1) {
x <- compute(x)
output <- c(output, x)
}
return(output)
}
The algo
根据该函数,函数将输入 X 的整个路径返回到 1。如您所知,output
变量动态增长,使用c()
(组合)功能。
还有其他选择吗?列表增长得更快吗?我是否应该采用一些经典的动态向量逻辑,例如初始化一个空的 N 大小向量并在每次满时将其加倍?
EDIT:请不要介意尝试优化我的帮助函数的结构方式。我明白了,但这不是重点!我只关心c()
功能及其替代方案。
Update
根据您的编辑,也许您可以检查以下解决方案
algo_TIC2 <- function(x) {
res <- x
repeat {
u <- tail(res, 1)
if (u != 1) {
res[length(res) + 1] <- if (u %% 2) 3 * u + 1 else u / 2
} else {
return(res)
}
}
}
您可以使用如下递归
compute <- function(x) if (x %% 2) 3*x + 1 else x / 2
algo_TIC1 <- function(x) {
if (x == 1) {
return(1)
}
c(x, algo_TIC1(compute(x)))
}
你会看到
> algo_TIC1(3000)
[1] 3000 1500 750 375 1126 563 1690 845 2536 1268 634 317 952 476 238
[16] 119 358 179 538 269 808 404 202 101 304 152 76 38 19 58
[31] 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16
[46] 8 4 2 1
如果您不需要任何辅助功能,即compute
, 你可以试试
algo_TIC1 <- function(x) {
if (x == 1) {
return(1)
}
c(x, algo_TIC1(if (x %% 2) 3*x + 1 else x / 2))
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)