如果您正在寻找这样的东西是如何工作的,这就是我在没有使用二进制文件的 php 库的情况下实现它的方式。
function search_get_combos($query){
$list = explode(" ", $query);
$bits = count($list); //bits of binary number equal to number of words in query;
//Convert decimal number to binary with set number of bits, and split into array
$dec = 1;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
while($dec < pow(2, $bits)) {
//Each 'word' is linked to a bit of the binary number.
//Whenever the bit is '1' its added to the current term.
$curterm = "";
$i = 0;
while($i < ($bits)){
if($binary[$i] == 1) {
$curterm .= $list[$i]." ";
}
$i++;
}
$terms[] = $curterm;
//Count up by 1
$dec++;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
}
return $terms;
}
请注意,这将只返回唯一的组合,但可以轻松扩展以获取每个可能的组合顺序,因此在您的示例中输出:
Array
(
[0] => fish
[1] => dog
[2] => dog fish
[3] => cat
[4] => cat fish
[5] => cat dog
[6] => cat dog fish
)
编辑(更多说明)
基础理论
首先,您可能知道的二进制数是一串 1 和 0。数字的长度是它具有的“位”数,例如。该数字011001
有 6 位(如果您感兴趣,数字 25)。然后如果数字的每一位对应于其中一个项,每次向上计数,如果位为 1,则该项包含在输出中,而如果为 0,则忽略。这就是正在发生的事情的基本理论。
深入研究代码
PHP 无法以二进制计数,但您可以将小数转换为二进制。所以这个函数实际上以十进制计数,并将其转换为二进制。但是由于位数很重要,因为每个术语都需要自己的位,因此您需要添加前导 0,这就是该位的作用:str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT)
现在这个函数使用了一个while循环,但是由于它需要循环的次数取决于有多少项,所以需要做一些数学运算。如果您曾经使用过二进制,您就会知道您可以制作的最大数字是 2^n(其中 n 是位数)。
我认为这应该涵盖了该功能的所有令人困惑的部分,如果我遗漏了什么,请告诉我。
看看发生了什么
使用下面的代码输出使用的逻辑,这样看可能更有意义!
function search_get_combos_demo($query){
$list = explode(" ", $query);
$bits = count($list);
$dec = 1;
while($dec < pow(2, $bits)) {
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
$curterm = "";
$i = 0;
while($i < ($bits)){
if($binary[$i] == 1) {
$curterm[] = $list[$i]." ";
}
$i++;
}
//-----DISPLAY PROCESS-----//
echo "Iteration: $dec <table cellpadding=\"5\" border=\"1\"><tr>";
foreach($binary as $b){
echo "<td>$b</td>";
}
echo "</tr><tr>";
foreach($list as $l){
echo "<td>$l</td>";
}
echo "</tr></table>Output: ";
foreach($curterm as $c){
echo $c." ";
}
echo "<br><br>";
//-----END DISPLAY PROCESS-----//
$terms[] = $curterm;
$dec++;
}
return $terms;
}