PHP数组组合
我有一个由7个数字组成的数组(1,2,3,4,5,6,7),我想从中选择5个数字,如PHP数组组合,php,arrays,combinations,Php,Arrays,Combinations,我有一个由7个数字组成的数组(1,2,3,4,5,6,7),我想从中选择5个数字,如 (1,2,3,4,5),(1,2,3,4,6),(1,2,3,4,7)。 请注意,(1,2,3,4,5)等于(4,5,3,1,2),因此输出中只应包括其中一个 我想知道PHP中是否有函数或任何算法可以做到这一点? 我不知道从哪里开始。 你能帮我吗 我希望将7个给定数字的所有组合(它们取自一个数组)放入5个插槽中,不考虑顺序。您可以使用此处找到的解决方案 如果链接断开,这是代码 class Combination
(1,2,3,4,5),(1,2,3,4,6),(1,2,3,4,7)。
请注意,(1,2,3,4,5)等于(4,5,3,1,2),因此输出中只应包括其中一个 我想知道PHP中是否有函数或任何算法可以做到这一点? 我不知道从哪里开始。 你能帮我吗
我希望将7个给定数字的所有组合(它们取自一个数组)放入5个插槽中,不考虑顺序。您可以使用此处找到的解决方案 如果链接断开,这是代码
class Combinations implements Iterator
{
protected $c = null;
protected $s = null;
protected $n = 0;
protected $k = 0;
protected $pos = 0;
function __construct($s, $k) {
if(is_array($s)) {
$this->s = array_values($s);
$this->n = count($this->s);
} else {
$this->s = (string) $s;
$this->n = strlen($this->s);
}
$this->k = $k;
$this->rewind();
}
function key() {
return $this->pos;
}
function current() {
$r = array();
for($i = 0; $i < $this->k; $i++)
$r[] = $this->s[$this->c[$i]];
return is_array($this->s) ? $r : implode('', $r);
}
function next() {
if($this->_next())
$this->pos++;
else
$this->pos = -1;
}
function rewind() {
$this->c = range(0, $this->k);
$this->pos = 0;
}
function valid() {
return $this->pos >= 0;
}
protected function _next() {
$i = $this->k - 1;
while ($i >= 0 && $this->c[$i] == $this->n - $this->k + $i)
$i--;
if($i < 0)
return false;
$this->c[$i]++;
while($i++ < $this->k - 1)
$this->c[$i] = $this->c[$i - 1] + 1;
return true;
}
}
foreach(new Combinations("1234567", 5) as $substring)
echo $substring, ' ';
类组合实现迭代器
{
受保护的$c=null;
受保护的$s=null;
受保护的$n=0;
受保护$k=0;
受保护的$pos=0;
函数构造($s,$k){
if(is_数组($s)){
$this->s=array\u值($s);
$this->n=计数($this->s);
}否则{
$this->s=(字符串)$s;
$this->n=strlen($this->s);
}
$this->k=$k;
$this->revind();
}
函数键(){
返回$this->pos;
}
函数电流(){
$r=数组();
对于($i=0;$i<$this->k;$i++)
$r[]=$this->s[$this->c[$i]];
返回为数组($this->s)$r:内爆(“”,$r);
}
函数next(){
如果($this->_next())
$this->pos++;
其他的
$this->pos=-1;
}
函数倒带(){
$this->c=范围(0,$this->k);
$this->pos=0;
}
函数valid(){
返回$this->pos>=0;
}
受保护函数_next(){
$i=$this->k-1;
而($i>=0&&$this->c[$i]==$this->n-$this->k+$i)
$i--;
如果($i<0)
返回false;
$this->c[$i]++;
而($i++<$this->k-1)
$this->c[$i]=$this->c[$i-1]+1;
返回true;
}
}
foreach(新组合(“1234567”,5)作为$substring)
echo$substring';
12345 12346 12347 12356 12357 12367 12456 12457 12467 12567 13456 13457 13467 13567 14567 23456 23456 234567 23467 23567 24567 34567梨内存储库完全满足您的需求:
返回所有组合和置换的包,不带
给定集合和子集大小的重复。关联数组是
保存
另一种基于堆栈的解决方案。它退出得很快,但会消耗很多内存 希望这能帮助别人 详细内容:
$total = count($array);
$i0 = -1;
for ($i1 = $i0 + 1; $i1 < $total; $i1++) {
for ($i2 = $i1 + 1; $i2 < $total; $i2++) {
for ($i3 = $i2 + 1; $i3 < $total; $i3++) {
for ($i4 = $i3 + 1; $i4 < $total; $i4++) {
for ($i5 = $i4 + 1; $i5 < $total; $i5++) {
$record = array();
for ($i = 1; $i <= $k; $i++) {
$t = "i$i";
$record[] = $array[$$t];
}
$callback($record);
}
}
}
}
}
函数_组合($number,$length)
{
$combines=array();
$stack=array();
//每个组合都可以订购
排序(数字);
//启动
数组\u推送($stack,array)(
'store'=>array(),
“选项”=>$number,
));
while(true){
//弹出一个项目
$item=array\u pop($stack);
//栈尾
如果(!$项目){
打破
}
//有效存储
如果($length$n){
$newStore=$item['store'];
$newStore[]=$n;
//每台联合收割机都可以订购
//因此,只接受大于存储编号的选项
$newOptions=array_slice($item['options',$index+1);
//推送新项目
数组\u推送($stack,array)(
'store'=>$newStore,
“选项”=>$newOptions,
));
}
}
返回$组合;
}
新的解决方案,优化了组合算法的速度和内存
心态:生成K个数字的组合。新的解决方案将使用K'for'语句。一个代表一个数字。
例如:$K=5表示使用了5个“for”语句
function combine($array, $k, $callback)
{
$total = count($array);
$init = '
$i0 = -1;
';
$sample = '
for($i{current} = $i{previous} + 1; $i{current} < $total; $i{current}++ ) {
{body}
}
';
$do = '
$record = array();
for ($i = 1; $i <= $k; $i++) {
$t = "i$i";
$record[] = $array[$$t];
}
$callback($record);
';
$for = '';
for ($i = $k; $i >= 1; $i--) {
switch ($i) {
case $k:
$for = str_replace(['{current}', '{previous}', '{body}'], [$i, $i - 1, $do], $sample);
break;
case 1:
$for = $init . str_replace(['{current}', '{previous}', '{body}'], [$i, $i - 1, $for], $sample);
break;
default:
$for = str_replace(['{current}', '{previous}', '{body}'], [$i, $i - 1, $for], $sample);
break;
}
}
// execute
eval($for);
}
改进了这一点,以使用关联数组:
函数唯一组合($values,$minLength=1,$maxLength=2000){
$count=计数($value);
$size=pow(2$count);
$keys=数组_键($values);
$return=[];
对于($i=0;$i<$size;$i++){
$b=sprintf(“%0”。$count.b”,$i);
$out=[];
对于($j=0;$j<$count;$j++){
如果($b[$j]=='1'){
$out[$keys[$j]]=$value[$keys[$j]];
}
}
如果(count($out)>=$minLength&&count($out)'xyz',
“b”=>“pqr”,
]);
结果:
Array
(
[0] => Array
(
[1] => b
)
[1] => Array
(
[0] => a
)
[2] => Array
(
[0] => a
[1] => b
)
)
[
[1,2,3,4], [1,2,3], [1,2,4], [1,3,4], [2,3,4], [1,2], [1,3], [1,4], [2,3], [2,4], [3,4], [1], [2], [3], [4]
]
它仍然适用于非关联阵列:
print_r(唯一组合(['a','b']);
结果:
Array
(
[0] => Array
(
[1] => b
)
[1] => Array
(
[0] => a
)
[2] => Array
(
[0] => a
[1] => b
)
)
[
[1,2,3,4], [1,2,3], [1,2,4], [1,3,4], [2,3,4], [1,2], [1,3], [1,4], [2,3], [2,4], [3,4], [1], [2], [3], [4]
]
我需要一个包含子集的组合函数,所以我接受了
@Nguyen Van Vinh
的答案,并根据我的需要对其进行了修改
如果将[1,2,3,4]
传递给函数,它将返回每个唯一的组合和子集,排序如下:
下面是函数:
函数获取长度为($numbers,$length)的组合{
$result=array();
$stack=array();
//每个组合都可以订购
排序(数字);
//启动
数组\u推送($stack,array)(
'store'=>array(),
“选项”=>$number,
));
while(true){
//弹出一个项目
$item=array\u pop($stack);
//栈尾
如果(!$项目)中断;
//有效存储
如果($length$n){
$newStore=$item['store'];
$newStore[]=$n;
//每个联合收割机都可以订购,因此只接受大于存储编号的选项
$newOptions=array_slice($item['options',$i+1);
//数组\取消移位以进行数字排序,数组\推送以反转
数组\u取消移位($堆栈,数组(
'store'=>$newStore,
“选项”=>$newOptions,
));
}
}
返回$result;
}
函数get_all_组合($number){
$length=计数($number);
$result=[];
而($length>0){
$result=array_merge($result,get_compositions_with_length($numbers,$length));
$length--;
}
返回$result;
}
$numbers=[1,2,3,4];
$r
$k = 5;
$array = array(1, 2, 3, 4, 5, 6, 7);
$callback = function ($record) {
echo implode($record) . "\n";
};
combine($array, $k, $callback);
Array
(
[0] => Array
(
[b] => pqr
)
[1] => Array
(
[a] => xyz
)
[2] => Array
(
[a] => xyz
[b] => pqr
)
)
Array
(
[0] => Array
(
[1] => b
)
[1] => Array
(
[0] => a
)
[2] => Array
(
[0] => a
[1] => b
)
)
[
[1,2,3,4], [1,2,3], [1,2,4], [1,3,4], [2,3,4], [1,2], [1,3], [1,4], [2,3], [2,4], [3,4], [1], [2], [3], [4]
]