当前位置: 首页 > 知识库问答 >
问题:

将for循环嵌套为更简洁的结构

傅砚
2023-03-14

最近,我的一位朋友问我是否可以在R中列出一个由step分隔的N数字列表,这些数字的总和为1。例如,向量seq(0.1,1,0.1)中3个数字的所有可能组合等于1。顺序并不重要。

我一直在使用expand.grid,但是随着数量的增加,内存需求激增。由于顺序不重要,我们认为只考虑一些组合来减少矩阵。如果我们这样做111表示值c(0.1,0.1,0.1),123表示c(0.1,0.2,0.3),我们只考虑111, 112, 113 ... 119, 122, 123, ... 129, 133...等等。

请注意,我们排除了121、131和132,因为它们等同于112、113和123。这大大减少了要测试的组合的数量。为此,我们使用嵌套for循环,如下所示:

step=.1
lst=list()
for(i in seq(step,1,step)){
  for(j in seq(i,1,step)){
    for(k in seq(j,1,step)){
          print(c(i,j,k));if(sum(c(i,j,k))==1){lst=append(lst,list(c(i,j,k)))}
    }
  }
}
do.call("rbind",lst)

这是可行的,但我想让它更灵活。现在,为了比较4个数字而不是3个,我需要编写一个新的for循环。我在想一个类似于上面嵌套循环的函数all_comb(向量,N),但是我找不到它,也不知道如何优雅地实现它。

谢谢你!

共有1个答案

太叔豪
2023-03-14

如果有长向量和高Ns,这样的函数可能会变得混乱,但这是绝对可行的。我写了一篇很快的文章,也许可以重构它,但它是有效的。

它创建可添加的向量索引的唯一向量列表。然后,它使用这个列表来计算和,并将它们作为向量返回,并将计算作为名称添加。

all_comb = function(vector,N){
  com = as.list(1:length(vector))
  names(com) = as.character(1:length(vector))
  for(i in 2:N){
    nl = list()
    for(e in com){
      for(vi in 1:length(vector)){
        combo = c(e,vi)
        combo = combo[order(combo)]
        nl[[paste(combo,collapse="+")]]=combo
      }
    }
    com = nl
  }
  
  for(i in 1:length(com)){
    com[[i]] = sum(vector[com[[i]]])
  }
  
  return(unlist(com))
  
}

为了用您的示例进行测试,我得到:

> result = all_comb(seq(0.1,1,.1),3)
> print(head(result,n=15))
 1+1+1  1+1+2  1+1+3  1+1+4  1+1+5  1+1+6  1+1+7  1+1+8  1+1+9 1+1+10  1+2+2  1+2+3  1+2+4  1+2+5  1+2+6 
   0.3    0.4    0.5    0.6    0.7    0.8    0.9    1.0    1.1    1.2    0.5    0.6    0.7    0.8    0.9 

> print(names(result)[result==1])
[1] "1+1+8" "1+2+7" "1+3+6" "1+4+5" "2+2+6" "2+3+5" "2+4+4" "3+3+4"

这意味着第一、第一和第八个元素等于1,或者第一、第二和第七个元素等于1,依此类推。

您可以在名称上使用str分裂()来获取原始索引。

 类似资料:
  • 和其他编程语言一样, Java 允许循环嵌套。如果把一个循环放在另一个循环体内,那么就可以形成嵌套循环。 嵌套循环既可以是 for循环嵌套 while 循环,也可以是 while 循环嵌套 do-while 循环 …… 即各种类型的循环都可以作为外层循环,也可以作为内层循环。 当程序遇到嵌套循环时,如果外层循环的循环条件允许,则开始执行外层循环的循环体,而内层循环将被外层循环的循环体来执行——只是

  • 问题内容: 我不知道这是否是一个愚蠢的问题,但是我需要在不使用递归的情况下动态更改for循环的数量。 例如,如果n = 3,则需要3个嵌套的for循环。 如果n = 5: 有没有什么方法可以做到这一点而无需递归?另一个问题:Java中多重调度的用途是什么?我正在尝试用一种方法编写代码,它应该在参数的不同情况下运行不同的事件。否,如果声明/三元经营者/案件。 注意:我只能使用一种方法(部分问题),并

  • 我对确定上述代码的BigO有点困惑。如果在最外层的循环中,则为(int x=1;x 然而,考虑到最外层循环迭代n 2次,这会改变bigO还是加法常数无关紧要的规则?最后,如果最内层循环迭代n 2次而不是n,会改变什么吗? 非常感谢。

  • 我有一个嵌套的for循环,但是它会减慢一点处理速度,我如何才能使嵌套循环高效。我需要的是对于外循环的每个值,内循环继续其所有迭代。但是,我不认为它会像两个嵌套循环那样影响计算。我的第二个问题是,循环会影响速度还是会支持我的现象? 我的代码:

  • 对Java来说很新鲜,我在大学的一个入门班做一个项目。我正在尝试做一个方法,在String数组中搜索输入的状态并返回索引。如果用户输入不在数组中的查询,我希望它要求一个新的状态来搜索。我的例外是说“变量statePotion可能尚未初始化。”下面是代码。 提前谢谢!

  • 问题内容: 目前,我正在为Java测试学习。在学习期间,我遇到了一个小问题。 在此for循环中: 输出为: 我的问题是,我不了解。当我阅读这段代码时,我一直认为它应该看起来像这样: 为什么不是这样? 问题答案: i的每次迭代都将开始j的全新迭代。 因此,从i == 1开始,然后在循环中j == 1,2,3。然后i == 2,然后j == 1,2,3循环,依此类推。 一次一步地执行它,这将是有意义的