如何使用R中的递归创建长度为n的所有2 ^ n个二进制序列的矩阵?

时间:2019-10-15 16:34:53

标签: r recursion binary

我知道我可以为此使用expand.grid,但是我正在尝试学习实际的编程。我的目标是采用下面的内容,并使用递归获得长度为n的所有2 ^ n个二进制序列。

我可以在n = 1的情况下执行此操作,但是我不明白如何以递归方式使用相同的函数来获得更高尺寸的答案。

这里是n = 1的地方:

binseq <- function(n){
  binmat <- matrix(nrow = 2^n, ncol = n)
  r <- 0 #row counter
  for (i in 0:1) {
        r <- r + 1
        binmat[r,] <- i
    }
  return(binmat)
  }

我知道我可能必须在return语句中使用cbind。我的直觉说,return语句应该类似于cbind(binseq(n-1),binseq(n))。但是,老实说,我现在完全迷失了。

所需的输出基本上应该在n = 3时递归地产生它:


binmat <- matrix(nrow = 8, ncol = 3)
r <- 0 # current row of binmat
for (i in 0:1) {   
for (j in 0:1) {
for (k in 0:1) {
r <- r + 1
binmat[r,] <- c(i, j, k)}   
} 
}
binmat

它应该只是一个矩阵,因为递归地填充了binmat。

1 个答案:

答案 0 :(得分:0)

我迅速编写了此函数,以生成给定 N 个字符的所有 N ^ K 个长度为 K 的排列。希望它会有用。

gen_perm <- function(str=c(""), lst=5, levels = c("0", "1", "2")){
  if (nchar(str) == lst){
    cat(str, "\n")
    return(invisible(NULL))
  }
  for (i in levels){
    gen_perm(str = paste0(str,i), lst=lst, levels=levels)
  }
}

# sample call
gen_perm(lst = 3, levels = c("x", "T", "a"))

我有更多时间会回到您的问题上。

更新 我修改了上面的代码以解决您的问题。请注意,要填充的矩阵位于全局环境中。该函数还使用tmp变量将行传递到全局环境。这是我解决问题的最简单方法。也许还有其他方法。

levels <- c(0,1)
nc <- 3

m <- matrix(numeric(0), ncol = nc)

gen_perm <- function(row=numeric(), lst=nc, levels = levels){
  if (length(row) == lst){
    assign("tmp", row, .GlobalEnv)
    with(.GlobalEnv, {m <- rbind(m, tmp); rownames(m) <- NULL})
    return(invisible(NULL))
  }
  for (i in levels){
    gen_perm(row=c(row,i), lst=lst, levels=levels)
  }
}

gen_perm(lst=nc, levels=levels)

更新2 要获得您提供的预期输出,请运行

m <- matrix(numeric(0), ncol = 3)
gen_perm(lst = 3, levels = c(0,1))
m

levels指定要生成的值的范围(在本例中为二进制),以生成排列,m是一个空矩阵以填充,gen_perm生成行并将其添加到矩阵mlst是排列的长度(与矩阵中的列数匹配)。