php通过排列组合实现1到9数字相加都等于20的方法

这篇文章主要介绍了php通过排列组合实现1到9数字相加都等于20的方法,实例分析了php排列组合数学运算的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下。

本文实例讲述了php通过排列组合实现1到9数字相加都等于20的方法,分享给大家供大家参考,具体实现方法如下:

  1. <?php
  2. set_time_limit(0);
  3. /*
  4. 函数说明:huoqu_zhuhe($eq,$jiashu,$isone=0)
  5. 参数说明:$eq---几个数相加的总和;
  6. $jiashu-------加数数组:$jiashu=array(1,2,3,4,5,6,7,8,9),可以使用的加数;
  7. $isone---是否要每次使用不同的加数,唯一性,1是 0 不,默认1
  8. 返回类型:数组,数字以+相连的字符串:[0] => 3+8+9 [1] => 4+7+9
  9. 测试效果:1:对于加数数组比较小的,速度可以,过大的话,有些慢;2:每次可以使用不同的加数的,处理会变慢
  10. 采用的方法是:生成所有可能排列,对排列处理过滤重复的,得到组合
  11. */
  12. function huoqu_zhuhe($eq,$jiashu,$isone=1)
  13. {if(emptyempty($jiashu)||!is_array($jiashu)){echo 'error:加数必须数组';return false;}
  14. $feishu=0;
  15. for($i=0;$i<count($jiashu);$i++){
  16. if(!is_numeric($jiashu[$i])){$feishu=1;break;}
  17. }
  18. if($feishu==1){echo 'error;数组中必须是合法的数字';return false;}
  19. $lian=$jiashu;
  20. $savearr=array();
  21. while(!emptyempty($lian)){
  22. //echo 1;
  23. $newarr=array();
  24. $k=0;
  25. for($i=0;$i<count($lian);$i++){
  26. $lianstr=$lian[$i];
  27. $arr=explode('+',$lianstr);
  28. $nowhe=array_sum($arr);
  29. //echo $nowhe;
  30. for($j=0;$j<count($jiashu);$j++){
  31. $savestr=$lianstr.'+'.$jiashu[$j];
  32. if($isone==1&&in_array($jiashu[$j],$arr))continue;
  33. if(($nowhe+$jiashu[$j])>$eq)break;
  34. else if(($nowhe+$jiashu[$j])==$eq){
  35. $savearr[]=$savestr;
  36. }
  37. else{$newarr[$k]=$savestr;$k++;}
  38. }//end for($j=0;$j<count($jiashu)
  39. }// end for($i=0;$i
  40. $lian=$newarr;
  41. }//end while(!empty($lian))
  42. //print_r($savearr);
  43. //生成组合部分,过滤重复,2个数组以一个为参考,看另一个是否能通过移动达到匹配,可以,过滤
  44. $isguolu=array();//存储对应的id的取舍 0取 1舍
  45. for($i=0;$i<count($savearr);$i++){
  46. $isguolu[]=0;
  47. }//初始化全部0
  48. for($i=0;$i<count($savearr);$i++){
  49. $arr1=explode('+',$savearr[$i]);
  50. $len1=count($arr1);
  51. for($j=$i+1;$j<count($savearr);$j++){
  52. $arr2=explode('+',$savearr[$j]);
  53. $len2=count($arr2);
  54. if($len1!=$len2)continue;
  55. if($isguolu[$j]==1)continue;
  56. //比较$arr1和$arr2开始
  57. $jishu=0;
  58. for($i1=0;$i1<count($arr1);$i1++){
  59. $a=$arr1[$i1];
  60. $isyou=0;
  61. for($i2=$i1;$i2<count($arr2);$i2++){
  62. if($a==$arr2[$i2]){
  63. $jishu++;
  64. $isyou=1;
  65. $t=$arr2[$i1];
  66. $arr2[$i1]=$arr2[$i2];
  67. $arr2[$i2]=$t;
  68. break;
  69. }
  70. }//end for($i2=0
  71. if($isyou==0)break;
  72. }// end for($i1=0;$i1<count($arr1);
  73. if($jishu==$len1)$isguolu[$j]=1;
  74. }//end for($j=$i+1;
  75. }//end for($i=0;$i<count($savearr);$i++)
  76. //print_r($isguolu);
  77. //根据过滤数组选择
  78. $newarr=array();
  79. for($i=0;$i<count($savearr);$i++){
  80. if($isguolu[$i]==0)$newarr[]=$savearr[$i];
  81. }
  82. //print_r($newarr);
  83. return $newarr;
  84. }
  85. //下面是一个测试
  86. //取用1,2,3,4,5,6,7,8,9相加所有等于20的组合
  87. $jiashu=array(1,2,3,4,5,6,7,8,9);
  88. $eq=20;
  89. if($jieguo=huoqu_zhuhe($eq,$jiashu,1))print_r($jieguo);
  90. ?>

运行结果如下:

  1. Array
  2. (
  3. [0] => 3+8+9
  4. [1] => 4+7+9
  5. [2] => 5+6+9
  6. [3] => 5+7+8
  7. [4] => 1+2+8+9
  8. [5] => 1+3+7+9
  9. [6] => 1+4+6+9
  10. [7] => 1+4+7+8
  11. [8] => 1+5+6+8
  12. [9] => 2+3+6+9
  13. [10] => 2+3+7+8
  14. [11] => 2+4+5+9
  15. [12] => 2+4+6+8
  16. [13] => 2+5+6+7
  17. [14] => 3+4+5+8
  18. [15] => 3+4+6+7
  19. [16] => 1+2+3+5+9
  20. [17] => 1+2+3+6+8
  21. [18] => 1+2+4+5+8
  22. [19] => 1+2+4+6+7
  23. [20] => 1+3+4+5+7
  24. [21] => 2+3+4+5+6
  25. )

希望本文所述对大家的php程序设计有所帮助。