2013-01-23 104 views
-1

例如为3的输入将返回[1,1,1],[2,1]和[1,2]如何返回给定整数给定正整数的所有数字序列?

我知道很多的组合/排列问题涉及调用一个递归函数本身在循环内,但我无法看到适用于此问题的适当方式。

它我试图抓住一个概念,这里是我迄今为止...

function numberToAddends($number, $arr, $k){ 
    for ($i = 0; $i < $number; $i++) { 
     $arr[$k] = $i; 
     numberToAddends($k-$i, $arr, $k + 1); 
    } 

    if($k <=0){ 
     print_r($arr); 
    } 
} 

对于测试输入,你可以使用像numberToAddends(3,$ ARR,0);

我在想正确的道路吗?任何人都可以提供完整的PHP语法来解决这个问题以及评论代码吗?

+0

它不应该给'[3]'作为解决方案吗? – phimuemue

+1

*评论代码*,一些咖啡,或许是一个很好的甜甜圈? – 2013-01-23 19:53:15

+0

不,原来的号码都是 – user784637

回答

1

下面是通过重用子结果从1至ň解决这个问题的算法:

$number = 3; 
$addends = array(); 
for ($x=1; $x<=$number; $x++) { 
    $addends[$x] = array(); 
    for ($y=$x-1; $y>0; $y--) { 
     foreach ($addends[$y] as $z) { 
      $addends[$x][] = array_merge($z, array($x-$y)); 
     } 
    } 
    $addends[$x][] = array($x); 
} 
var_dump($addends); 

这将构建组合的任何已知结果žX设置结果任何ÿ < XXy中的差最后x本身。

2

您正在寻找的概念是一个数字的“整数分区”。谷歌应该为您提供很多代码,或者查看my blog获取解释和代码。

基本思想是一个简单的递归过程。有一个单独的分区0,空的set()。有一个单独的分区1,集合(1)。有两个分区2,集合(1 1)和(2)。有三个分区3,集合(1 1 1),(1 2)和(3)。有5个分区,分别为(1 1 1 1),(1 1 2),(1 3),(2 2)和(4)。有5个分区,集合(1 1 1 1 1),(1 1 1 2),(1 2 2),(1 1 3),(1 4),(2 3)和(5)。等等。在每种情况下,下一个更大的分区集合通过将所有由n-x的分区形成的集合中的每个小于或等于所需整数n的整数x相加来消除任何重复。

相关问题