如何保持循环直到达到设定的数字

how to keep a loop going until it reaches a set number

我有这样的数据

df <- seq(5,10)

我选第一个号码

t <- df[1]

我想执行以下操作(Collat​​z 序列):

示例:

我做了这个,但我不知道如何把它组合起来

if( (df[1]%%2) == 0) {
mydf <- df[1]* 3+1
} else {
mydf <- df[1]/2

我发现这对当时的每个数字都有效

mydf <-  NULL
n <- 5
while (n != 1) {
  if (n %% 2 == 0) {
    n <- n / 2
  } else {
    n <- (n * 3) + 1
  }
  mydf <- c(mydf, cbind(n))
}

我每次都应该给出一个数字,我怎样才能一个接一个地得到数字并将中间结果保存为行?

在每个数字的 for 循环中使用您的代码。

df <- seq(5,10)
mydf <- numeric(length(df))

for(i in seq_along(df)) {
  n <- df[i]
  while (n != 1) {
    if (n %% 2 == 0) {
      n <- n / 2
    } else {
      n <- (n * 3) + 1
    }
  }
  mydf[i] <- n
}

mydf
#[1] 1 1 1 1 1 1

要保存中间步骤,请使用列表。

df <- seq(5,10)
mydf <- vector('list', length(df))

for(i in seq_along(df)) {
  n <- df[i]
  mydf[[i]][1] <- n
  while (n != 1) {
    if (n %% 2 == 0) {
      n <- n / 2
    } else {
      n <- (n * 3) + 1
    }
    mydf[[i]] <- c(mydf[[i]], n)
  }
}

mydf
#[[1]]
#[1]  5 16  8  4  2  1

#[[2]]
#[1]  6  3 10  5 16  8  4  2  1

#[[3]]
# [1]  7 22 11 34 17 52 26 13 40 20 10  5 16  8  4  2  1

#[[4]]
#[1] 8 4 2 1

#[[5]]
# [1]  9 28 14  7 22 11 34 17 52 26 13 40 20 10  5 16  8  4  2  1

#[[6]]
#[1] 10  5 16  8  4  2  1

您可以使用 Recursion 函数:

fun <- function(x){
  if (x == 1) 1     # if 1 RETURN 1
  else if(x %% 2) Recall(x*3 + 1)    # If odd, multiply by 3 add 1 and repeat
  else Recall(x/2)     # otherwise divide by 2 and repeat
}

您的 fun 现在可以处理个位数,即:

fun(5)
[1] 1

然后我们可以对其进行矢量化,使其在矢量上工作:

collatz <- Vectorize(fun)
collatz(seq(1, 10))
[1] 1 1 1 1 1 1 1 1 1 1

编辑:

如果您需要中间步骤:

fun <- function(x){
  if (x[1] == 1) rev(x)
  else if(x[1] %% 2) Recall(c(x[1]*3 + 1, x))
  else Recall(c(x[1]/2, x))
}
collatz <- Vectorize(fun)

collatz(seq(5,10))
[[1]]
[1]  5 16  8  4  2  1

[[2]]
[1]  6  3 10  5 16  8  4  2  1

[[3]]
 [1]  7 22 11 34 17 52 26 13 40 20 10  5 16  8  4  2  1

[[4]]
[1] 8 4 2 1

[[5]]
 [1]  9 28 14  7 22 11 34 17 52 26 13 40 20 10  5 16  8  4  2  1

[[6]]
[1] 10  5 16  8  4  2  1

这是另一个递归选项

f <- Vectorize(function(x) {
  if (x == 1) {
    return(1)
  }
  c(x, f(if (x %% 2) 3 * x + 1 else x / 2))
})

这给出了

> f(c(5:10))
[[1]]
[1]  5 16  8  4  2  1

[[2]]
[1]  6  3 10  5 16  8  4  2  1

[[3]]
 [1]  7 22 11 34 17 52 26 13 40 20 10  5 16  8  4  2  1

[[4]]
[1] 8 4 2 1

[[5]]
 [1]  9 28 14  7 22 11 34 17 52 26 13 40 20 10  5 16  8  4  2  1

[[6]]
[1] 10  5 16  8  4  2  1