情况:有5个问题有多个可能的答案。其中四个问题可以有一个答案,一个问题有一个或多个答案。任何问题都没有答案。
我想弄清楚这些答案的每一种可能组合。
我认为这不是this的副本,因为它处理单个字符或数字的可能排列。
我相信这个例子会产生230,400种可能的排列
$questions = array(
"q1" => array(
"1a",
"1b",
"1c"
),
"q2" => array(
"2a",
"2b",
"2c",
"2d"
),
"q3" => array(
"3a",
"3b",
"3c"
),
"q4" => array( // this question can have any number of these answers selected, or none
"4a",
"4b",
"4c",
"4d",
"4e",
"4f"
),
"q5" => array(
"5a",
"5b",
"5c"
)
);
答案 0 :(得分:0)
我希望我的问题是对的,这个答案对你有帮助......
除了你的例子之外,让我们介绍第二个数组,其中包含哪些问题可能有多个答案的信息:
$multi_questions = array('q4');
这将告诉我们下面描述的算法,问题4可能会选择任意数量的答案,而所有问题可能只有一个或没有答案。
为特定问题选择的答案集独立于任何其他问题。对于总共n
个可能答案和最多1个所选答案的问题,该问题的可能选择数为n+1
。如果问题允许选择多个答案,则该问题可能有2^n
种组合(每个答案都有两个选项:选择或未选择)。
在您的示例中,这会导致所选答案的4 * 5 * 4 * 2^6 * 4 = 20480
种可能组合的总数。这个数字的计算方法如下:
$combinations = 1;
foreach ($questions as $q => $answers)
{
if (in_array($q, $multi_questions))
$combinations *= 1 << count($answers);
else
$combinations *= count($answers) + 1;
}
如果您不仅对答案组合的数量感兴趣,而且想要全部生成它们,您可以使用如下算法。对于具有多个可能答案的问题,它将以二进制数给出的答案集编码。也就是说,数字001010
代表答案集['4c','4e']
。
$q_keys = array_keys($questions);
// Start with no answer selected for any question
$answer_set = array();
$q_max = array();
for ($i = 0; $i < count($q_keys); $i++)
{
$answer_set[$i] = 0;
$q_max[$i] = (in_array($q_keys[$i], $multi_questions))
? (1 << count($questions[$q_keys[$i]])) - 1
: count($questions[$q_keys[$i]]);
}
// Iterate over all combinations of answers
while ($answer_set[0] <= $q_max[0])
{
// Decode answer set to array of selected answers for each question
$answers = array();
for ($i = 0; $i < count($q_keys); $i++)
{
if (in_array($q_keys[$i], $multi_questions))
{
$answers[$q_keys[$i]] = array();
for ($a = 0; $a < count($questions[$q_keys[$i]]); $a++)
if (($answer_set[$i] & (1 << $a)) != 0) // Is the bit corresponding to answer no. $a set?
$answers[$q_keys[$i]][] = $questions[$q_keys[$i]][$a];
}
else
$answers[$q_keys[$i]] = ($answer_set[$i] > 0)
? array($questions[$q_keys[$i]][$answer_set[$i] - 1])
: array(); // Encode no answer as empty array
}
// Do something with the array of answers for each question ($answers)
// ...
// Forward the answer set
for ($i = count($q_keys) - 1; $i >= 0; $i--)
{
if (++$answer_set[$i] > $q_max[$i] && $i > 0)
$answer_set[$i] = 0;
else
break;
}
}