(转)php排列组合 1到9数字相加都等于20
<?php set_time_limit(0); /* 函数说明:huoqu_zhuhe($total,$num_array,$isone=0) 参数说明:$total---几个数相加的总和; $num_array-------加数数组:$num_array=array(1,2,3,4,5,6,7,8,9),可以使用的加数; $count 几个数相加,为零不限制 $isone---是否要每次使用不同的加数,唯一性,1是 0 不,默认1 返回类型:数组,数字以+相连的字符串:[0] => 3+8+9 [1] => 4+7+9 测试效果:1:对于加数数组比较小的,速度可以,过大的话,有些慢;2:每次可以使用不同的加数的,处理会变慢 采用的方法是:生成所有可能排列,对排列处理过滤重复的,得到组合 */ function huoqu_zhuhe($total, $num_array, $count = 0, $isone = 1){ if(empty($num_array) || !is_array($num_array)) { echo 'error:加数必须数组';return false; } $feishu=0; for($i=0; $i<count($num_array); $i++) { if(!is_numeric($num_array[$i])) { $feishu=1; break; } } if($feishu==1) { echo 'error;数组中必须是合法的数字';return false; } $lian=$num_array; $savearr=array(); while(!empty($lian)) { //echo 1; $newarr=array(); $k=0; for($i=0; $i<count($lian); $i++) { $lianstr = $lian[$i]; $arr = explode('+', $lianstr); $nowhe=array_sum($arr); for($j=0;$j<count($num_array);$j++) { $savestr=$lianstr.'+'.$num_array[$j]; if($isone==1 && in_array($num_array[$j],$arr)) continue; if(($nowhe+$num_array[$j])>$total) break; else if(($nowhe+$num_array[$j])==$total) { $savearr[]=$savestr; }else{ $newarr[$k]=$savestr;$k++; } }//end for($j=0;$j<count($num_array) }// end for($i=0;$i $lian=$newarr; }//end while(!empty($lian)) if ($count != 0) { foreach ($savearr as $key => $number) { $savearr_count = count(explode('+', $number)); if ($count != $savearr_count) unset($savearr[$key]); } } //生成组合部分,过滤重复,2个数组以一个为参考,看另一个是否能通过移动达到匹配,可以,过滤 $isguolu=array();//存储对应的id的取舍 0取 1舍 for($i=0;$i<count($savearr);$i++) { $isguolu[]=0; }//初始化全部0 for($i=0;$i<count($savearr);$i++) { $arr1=explode('+',$savearr[$i]); $len1=count($arr1); for($j=$i+1;$j<count($savearr);$j++) { $arr2=explode('+',$savearr[$j]); $len2=count($arr2); if($len1!=$len2) continue; if($isguolu[$j]==1) continue; //比较$arr1和$arr2开始 $jishu=0; for($i1=0;$i1<count($arr1);$i1++) { $a=$arr1[$i1]; $isyou=0; for($i2=$i1;$i2<count($arr2);$i2++) { if($a==$arr2[$i2]) { $jishu++; $isyou=1; $t=$arr2[$i1]; $arr2[$i1]=$arr2[$i2]; $arr2[$i2]=$t; break; } }//end for($i2=0 if($isyou==0)break; }// end for($i1=0;$i1<count($arr1); if($jishu==$len1)$isguolu[$j]=1; }//end for($j=$i+1; }//end for($i=0;$i<count($savearr);$i++) //print_r($isguolu); //根据过滤数组选择 $newarr=array(); for($i=0;$i<count($savearr);$i++) { if($isguolu[$i]==0)$newarr[]=$savearr[$i]; } //print_r($newarr); return $newarr; } //下面是一个测试 //取用1,2,3,4,5,6,7,8,9相加所有等于20的组合 $num_array=array(1,2,3,4,5,6,7,8,9,10); if($jieguo=huoqu_zhuhe(20,$num_array,4)) { echo '<pre>'; print_r($jieguo); } ?>