生成数字组合

Posted

技术标签:

【中文标题】生成数字组合【英文标题】:Generate a combination of numbers 【发布时间】:2012-04-26 07:56:15 【问题描述】:

我有一个包含两个变量的 php 页面:$nbRank$nbNumeric。根据这两个变量,我想生成一个包含所有现有组合的数组。例如:

如果$nbRank = 3$nbNumeric = 2 我会:

0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
1 0 1
1 0 2
1 1 0
1 1 1
1 1 2
1 2 0
1 2 1
1 2 2
2 0 0
2 0 1
2 0 2
2 1 0
2 1 1
2 1 2
2 2 0
2 2 1
2 2 2

所以,我创建了不同的循环和公式来获得最终结果,但它不起作用。这就是我所做的:

$result = array();

$nbIntRank = 0;
$nbIntNumeric = 0;
$nbRank = array();
$nbNumeric = array();

$nb_rangs = 3;
$nb_chiffres = 2;

for ($i = 1; $i <= $nb_rangs; $i++)
    $nbRank[$i] = 0;


$nbIntRank = count($nbRank);

for ($i = 0; $i <= $nb_chiffres; $i++)
    $nbNumeric[$i] = $i;


$nbIntNumeric = count($nbNumeric);

$algo = ($nb_rangs * ($nb_chiffres + 1)) * ($nb_rangs * ($nb_chiffres + 1));
$nbLine = $algo / ($nb_rangs);

$occ = 0;
for ($i = 0; $i < $nbLine; $i++)
    foreach ($nbRank as $nbrItem => $nbrValue)
        $result[$i][] = $nbrValue;
        $occ++;
    


echo '#############<br />';
echo '### DATAS ###<br />';
echo '#############<br /><br />';

echo '- Nb Elements : '.$algo.'<br />';
echo '- Nb Lines : '.$nbLine.'<br />';
echo '- Nb Valuable Occurency : '.$occ.'<br />';

echo '<br /><hr /><br />';
echo '##############<br />';
echo '### PARSER ###<br />';
echo '##############<br /><br />';

echo '<pre>';
var_dump($result);
echo '</pre>';

我设法用空值创建了我的最终数组(81 个值,27 行,每行 3 个元素),但它只包含 0。

【问题讨论】:

请贴出完整的代码,包括循环。 @AdamLiss 完成,我添加了完整的源代码。 @amit 是的,它可以帮助我,谢谢! :) 抱歉,我错误地删除了评论:\ @JohnSmeuth:回答之前提出的问题:“您也可以接受伪代码答案解决方案吗?” 【参考方案1】:

您表示您可以使用伪代码。抱歉,我无法为您的 php 代码提供具体的更正 [如果出现这些答案 - 它们可能更具教育意义],但我选择了 recursive 解决方案这个问题。

在递归的每一级中,尝试所有可能性,并调用相同的函数以找到一个较小尺寸的所有组合

伪代码:

findCombinations(range,size,sol,resultList):
  if (size ==0): #base clause
     resultList.append(copy(sol)) #making a copy of sol and appending it as a solution
     return
  for each i in (0,range):
     sol.append(i)
     findCombinations(range,size-1,sol,resultList) #recursive invokation, with smaller size
     sol.deleteLast() #clean up environment before next calls

使用findCombinations(3,3,[],resultList) 调用,其中[] 只是空列表,而resultList 将在算法完成后保存组合列表。此调用将获得所有大小为 3 且元素为 0、1、2 的组合。

复杂性说明: 可能性的数量呈指数增长 [O(rangesize)],因此如果您尝试使用 20,20 来调用它 - 对于任何解决方案都可能需要一些 [非常长] 时间。

【讨论】:

【参考方案2】:
$nbRank = 3;
$nbNumeric = 2;

foreach (range(0, base_convert(str_pad('', $nbRank, $nbNumeric), $nbNumeric+1, 10)) as $i) 
  echo str_pad(base_convert($i, 10, $nbNumeric+1), 3, 0, STR_PAD_LEFT) . PHP_EOL;

简单的想法:你想要的是从 0 到 X 的每个数字,基数为 $nbNumeric,因此我们只需将最大数转换为基数 10,使用常见的基于 10 的运算符对其进行迭代,然后将其转换回基数再次$nbNumeric

可能更具可读性,但实际上完全相同

$nbRank = 3;
$nbNumeric = 2;

// Top is "base_convert(222, 3, 10);" and therefore the upper limit
$top = base_convert(str_pad('', $nbRank, $nbNumeric), $nbNumeric+1, 10);
for ($i = 0; $i <= $top; $i++) 
    echo str_pad(base_convert($i, 10, $nbNumeric+1), 3, 0, STR_PAD_LEFT) . PHP_EOL;

【讨论】:

很有趣,我发现了一些我不知道的功能。谢谢!【参考方案3】:

这是一个递归解决方案:

$nbRank = 3;
$nbNumeric = 2;

function getCombinations ($length, $min, $max, $aStartingCombinations)

    if ($length == 1)
    
        return range ($min, $max);
    

    $final = array ();
    foreach (getCombinations ($length - 1, $min, $max, $aStartingCombinations) as $combination)
    
        for ($i = $min; $i <= $max; $i++)
        
            $final [] = $combination . $i;
        
    
    return $final;


print_r (getCombinations ($nbRank, 0, $nbNumeric, array ()));

【讨论】:

只是一个语义说明:这些不是排列,这些是更多的组合[排列没有重复,而在这里我们计算重复]。由于我不熟悉 php,因此我无法对代码提供任何反馈,因此无论如何我都不会攻击答案,只是提供更好的术语:)

以上是关于生成数字组合的主要内容,如果未能解决你的问题,请参考以下文章

数字组合生成器

设计生成所有 n 位数字组合的递归函数的最佳方法是啥?

生成每个可能的 7 位数字组合的算法 [关闭]

如何有效地生成组合而不重复,它们之间有特定的数字

生成C ++中N个数字中的所有R位数字(组合,迭代)?

从数字集 N 生成长度 k 的组合,顺序很重要,允许替换