如何实现这样的算法?

时间:2010-11-20 02:40:22

标签: php algorithm permutation combinations

假设有x个盒子,每个盒子包含一个字母A-Z的“库存”,每个字母库存为1个或更多。

现在说我需要以下内容:

  • 6 As
  • 2 Bs
  • 1 C

如何获得可以为我提供所需信件的所有可能组合/排列的列表?

该算法还需要生成盒子组合以满足我的要求。例如:假设Box-1只有4 As,Box-2有1 A而Box-3有1 A,我需要算法的结果来指定6个As可以在3个方框中实现。

解决此类问题的基本逻辑是什么。我需要为此考虑任何特定的算法吗?

编辑1:

根据dcp的建议,这是我尝试PHP实现:

$boxes = array(
    // box 1
    array(
        'A' => 6,
        'B' => 4,
        'C' => 10
    ),
    // box 2
    array(
        'A' => 8,
        'B' => 4,
        'C' => 2
    ),
    // box 3
    array(
        'A' => 1,
        'B' => 1,
        'C' => 0
    )
);

$n = count($boxes);

for ($mask = 0; $mask <= (1 << $n) - 1; $mask++)
{
    $tots = array();
    for ($i = 0; $i < $n; $i++)
    {
        if (((1 << $i) & $mask) != 0)
        {
            // this is a selected box for this mask, add the A's, B's etc. for this box to the total
            $tots[0] += $boxes[$i]['A'];
            $tots[1] += $boxes[$i]['B'];
            $tots[2] += $boxes[$i]['C'];
        }
        // check the tots array to see if it meets the letter requirements. If it does,
        // then this is a valid combination of boxes.
    }
}

1 个答案:

答案 0 :(得分:1)

如果盒子的数量相当小,比如25或更少,那么你可以使用位掩码对所有可能的盒子组合进行暴力破解:

// assume n is number of boxes, and boxes is the array of boxes
for(int mask = 0; mask <= (1<<n)-1; ++mask) {
  int tots[26];
  for(int i = 0; i < n; ++i) {
    if ( ((1<<i)&mask) != 0 ) {
      // this is a selected box for this mask, add the A's, B's etc. for this box to the total
      tots[0] += number of A's in box i
      tots[1] += number of B's in box i
      .
      .
    }
    // check the tots array to see if it meets the letter requirements. If it does, 
    // then this is a valid combination of boxes.
  }
}