【问题标题】:Algorithm to get combinations one by one without storing them into memory [duplicate]一个一个地获得组合而不将它们存储到内存中的算法[重复]
【发布时间】:2018-10-25 12:57:05
【问题描述】:

我有一个长 N 个整数的数组,我有一个输入整数 X。我需要用总和为 X 的整数组合填充整个数组。我需要找到所有可能的组合,顺序很重要,数组有固定长度(常量 N)。例如,如果 X=3 和 N=4 我需要得到这个:

[3, 0, 0, 0]
[2, 1, 0, 0]
[2, 0, 1, 0]
[2, 0, 0, 1]
[1, 2, 0, 0]
[1, 1, 1, 0]
[1, 1, 0, 1]
[1, 0, 2, 0]
[1, 0, 1, 1]
[1, 0, 0, 2]
[0, 3, 0, 0]
[0, 2, 1, 0]
[0, 2, 0, 1]
[0, 1, 2, 0]
[0, 1, 1, 1]
[0, 1, 0, 2]
[0, 0, 3, 0]
[0, 0, 2, 1]
[0, 0, 1, 2]
[0, 0, 0, 3]

此外,我不想将所有可能的组合存储在内存中,但我需要一一获取这些值。例如,当我上次调用方法 NEXT 时,我得到 [0, 2, 0, 1]。当我再次调用它时,我需要获得下一个组合 [0, 1, 2, 0]。当我再次调用它时,我需要得到 [0, 1, 1, 1] 等等。 有没有可以做到这一点的算法?谢谢

【问题讨论】:

  • 为避免内存问题,您可能希望存储一系列链式迭代器,这些迭代器仅保留它们到目前为止达到的索引
  • “我有一个整数数组[N]”和“数组中所有值的组合”。这个问题听起来很糟糕。 IE。如果您有一个像 {0,1,2,3} 这样的数组,则有 2^4 种可能的组合(在定义的组合意义上),并且只有以下组合匹配,例如3 {1,2}, {0,1,2}, {3}, {0,3}
  • @juvian 不是重复的,是不同的问题。
  • @Vojtech 完全一样,只是在您的情况下您不想使用超过 N 个数字,但是可以轻松修改提出的解决方案以添加该限制
  • 我更新了描述,希望现在区别更清楚了。

标签: java algorithm combinatorics


【解决方案1】:

我已经修改了 colex 中的合成生成以适合您的订单。
工作德尔福代码,我希望它是可以理解的(Dec(P) 等于P--

  function next(): Boolean;
  var
    nonzero, last: integer;
  begin
    last := C[n - 1];
    if last = x then  // the last composition
      Exit(False);

    C[n - 1] := 0;
    nonzero := n - 2;
    while C[nonzero] = 0 do //find the last nonzero element
       Dec(nonzero);

    Dec(C[nonzero]);
    C[nonzero + 1] := 1 + last;
    Exit(True);
   end;

begin
  n := 4;
  x := 3;
  SetLength(C, n);
  C[0] := x;
  Memo1.Lines.Add(ArrToStr(C));
  while next() do
    Memo1.Lines.Add(ArrToStr(C));

输出

3 0 0 0 
2 1 0 0 
2 0 1 0 
2 0 0 1 
1 2 0 0 
1 1 1 0 
1 1 0 1 
1 0 2 0 
1 0 1 1 
1 0 0 2 
0 3 0 0 
0 2 1 0 
0 2 0 1 
0 1 2 0 
0 1 1 1 
0 1 0 2 
0 0 3 0 
0 0 2 1 
0 0 1 2 
0 0 0 3 

【讨论】:

  • 太棒了,它非常简单,它完全符合我的需要。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-11-13
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多