当前位置:Gxlcms > PHP教程 > 对多个数组进行组合讨论

对多个数组进行组合讨论

时间:2021-07-01 10:21:17 帮助过:6人阅读

排列组合

假设有三个数组(实际不确定多少个数组):
$arr1 = array(1, 2, 3, 4);
$arr2 = array(10, 20, 30, 40);
$arr3 = array(100, 200, 300, 400);

要实现的结果:
array(
array(1,10,100),
array(1,10,200),
array(1,10,300),
array(1,10,400),
array(1,20,100),
array(1,20,200),
array(1,20,300),
array(1,20,400),
array(1,30,100),
...
);
不想用递归,但是也可以实现看看


回复讨论(解决方案)

本帖最后由 xuzuning 于 2013-09-12 07:58:13 编辑

  1. $a = [1, 2];$b = ['A', 'B', 'C'];$c = ['a', 'b'];$d = Descartes($a, $b, $c);print_r($d);function Descartes() { $d = func_get_args(); if( count($d) < 2 ) return current($d); $n = array_product( array_map('count', $d) ); array_walk( $d, function(&$v, $k, $n) { $v = array_chunk( call_user_func_array('array_merge', array_pad([$v], $n/count($v), $v)), 1); if($k==0) sort($v); }, $n); array_unshift($d, 'array_merge'); $d = call_user_func_array('array_map', $d); array_multisort(array_map(function($v) { return $v[0]; }, $d), $d); return $d;}
  1. Array( [0] => Array ( [0] => 1 [1] => A [2] => a ) [1] => Array ( [0] => 1 [1] => A [2] => b ) [2] => Array ( [0] => 1 [1] => B [2] => a ) [3] => Array ( [0] => 1 [1] => B [2] => b ) [4] => Array ( [0] => 1 [1] => C [2] => a ) [5] => Array ( [0] => 1 [1] => C [2] => b ) [6] => Array ( [0] => 2 [1] => A [2] => a ) [7] => Array ( [0] => 2 [1] => A [2] => b ) [8] => Array ( [0] => 2 [1] => B [2] => a ) [9] => Array ( [0] => 2 [1] => B [2] => b ) [10] => Array ( [0] => 2 [1] => C [2] => a ) [11] => Array ( [0] => 2 [1] => C [2] => b ))

嗯,这个是对的。#1 的有些毛病,传入4个数组就不对了

  1. $a = [1, 2];$b = ['A', 'B', 'C'];$c = ['a', 'b'];$d = ['D', 'E', 'F'];$r = Descartes($a, $b, $c);$r = Descartes($a, $b, $c, $d);print_r( array_map(function($v) { return join(',', $v); }, $r) );function Descartes() { $d = func_get_args(); if( count($d) < 2 ) return current($d); $n = array_product( array_map('count', $d) ); array_walk( $d, function(&$v, $k, $n) { $v = array_chunk( call_user_func_array('array_merge', array_pad([$v], $n/count($v), $v)), 1); }, $n); foreach($d as $i=>$t) { if($i == 0) { $r = $t; }else { array_multisort(array_map(function($v) { return $v[0]; }, $r), $r); $r = array_map('array_merge', $r, $t); } } return $r;}
  1. Array( [0] => 1,A,a,D [1] => 1,A,a,E [2] => 1,A,a,F [3] => 1,A,b,D [4] => 1,A,b,E [5] => 1,A,b,F [6] => 1,B,a,D [7] => 1,B,a,E [8] => 1,B,a,F [9] => 1,B,b,D [10] => 1,B,b,E [11] => 1,B,b,F [12] => 1,C,a,D [13] => 1,C,a,E [14] => 1,C,a,F [15] => 1,C,b,D [16] => 1,C,b,E [17] => 1,C,b,F [18] => 2,A,a,D [19] => 2,A,a,E [20] => 2,A,a,F [21] => 2,A,b,D [22] => 2,A,b,E [23] => 2,A,b,F [24] => 2,B,a,D [25] => 2,B,a,E [26] => 2,B,a,F [27] => 2,B,b,D [28] => 2,B,b,E [29] => 2,B,b,F [30] => 2,C,a,D [31] => 2,C,a,E [32] => 2,C,a,F [33] => 2,C,b,D [34] => 2,C,b,E [35] => 2,C,b,F)

嗯,这个是对的。#1 的有些毛病,传入4个数组就不对了

  1. $a = [1, 2];$b = ['A', 'B', 'C'];$c = ['a', 'b'];$d = ['D', 'E', 'F'];$r = Descartes($a, $b, $c);$r = Descartes($a, $b, $c, $d);print_r( array_map(function($v) { return join(',', $v); }, $r) );function Descartes() { $d = func_get_args(); if( count($d) < 2 ) return current($d); $n = array_product( array_map('count', $d) ); array_walk( $d, function(&$v, $k, $n) { $v = array_chunk( call_user_func_array('array_merge', array_pad([$v], $n/count($v), $v)), 1); }, $n); foreach($d as $i=>$t) { if($i == 0) { $r = $t; }else { array_multisort(array_map(function($v) { return $v[0]; }, $r), $r); $r = array_map('array_merge', $r, $t); } } return $r;}
  1. Array( [0] => 1,A,a,D [1] => 1,A,a,E [2] => 1,A,a,F [3] => 1,A,b,D [4] => 1,A,b,E [5] => 1,A,b,F [6] => 1,B,a,D [7] => 1,B,a,E [8] => 1,B,a,F [9] => 1,B,b,D [10] => 1,B,b,E [11] => 1,B,b,F [12] => 1,C,a,D [13] => 1,C,a,E [14] => 1,C,a,F [15] => 1,C,b,D [16] => 1,C,b,E [17] => 1,C,b,F [18] => 2,A,a,D [19] => 2,A,a,E [20] => 2,A,a,F [21] => 2,A,b,D [22] => 2,A,b,E [23] => 2,A,b,F [24] => 2,B,a,D [25] => 2,B,a,E [26] => 2,B,a,F [27] => 2,B,b,D [28] => 2,B,b,E [29] => 2,B,b,F [30] => 2,C,a,D [31] => 2,C,a,E [32] => 2,C,a,F [33] => 2,C,b,D [34] => 2,C,b,E [35] => 2,C,b,F)


看的有点晕,得慢慢看,用到了很多以前很少用的函数,不过这个中括号是什么写法? 5.3.12不支持
  1. array_pad([$v], $n/count($v), $v)

array() 可简化为 [] 是 php5.4 才有的吗?我怎么记得 php5.3 就是的呢?

简单注释一下:

  1. $d = func_get_args();//读取传入的参数到数组(php4) if( count($d) < 2 ) return current($d); $n = array_product( array_map('count', $d) ); //array_product 计算数组值的乘积(php5),array_map 返回经回调函数处理的数组(php4) array_walk( $d, function(&$v, $k, $n) {//用回调函数处理数组元素(php3)闭包写法(php5.3) $v = array_chunk( call_user_func_array('array_merge', array_pad([$v], $n/count($v), $v)), 1); }, $n);//array_chunk 切割数组(php4) //call_user_func_array 调用指定函数并传递参数数组(php4)对执行可变参数数量的函数很有用 foreach($d as $i=>$t) { if($i == 0) { $r = $t; }else { array_multisort(array_map(function($v) { return $v[0]; }, $r), $r); $r = array_map('array_merge', $r, $t); } }

除了简化 array() 为 [], 和使用了闭包写法外,没有什么新东西
闭包可用 create_function 函数改写

除了简化 array() 为 [], 和使用了闭包写法外,没有什么新东西
闭包可用 create_function 函数改写
嗯,5.3没有这种语法。怎么感觉php的语法和javascript的越来越像
多谢版主
我自己也写了个,比较?嗦

  1. function arr_combina3(){ $args = func_get_args(); $num = count($args); if(empty($args)){ return array(); }else if($num == 1){ return $args[0]; } $arr = array(); $i = 0; $j = 0; // 当前使用数组下标 $last_index = $num - 1; // 按传入顺序循环使用传入的参数数组 while($j <= $last_index){ if($j == $last_index){ // 当前使用数组为最后参数数组时 // 将最后传入的参数数组每一项分别加入组合 $tmp = $arr[$i]; foreach($args[$j] as $k=>$v){ $t = $tmp; $t[] = $v; $arr[$i] = $t; ++$i; } // 反向循环查找参数数组是否已使用完 for($n=$j-1; $n>=0; --$n){ $t = current($args[$n]); // 检测是否已到数组末尾 if(empty($t)){ // 已到数组末尾 if(0==$n){ // 已经是第一个数组的末尾,说明组合完成,停止组合 $num = 0; break 2; } reset($args[$n]); }else{ // 未到末尾时,修改当前使用数组下标 $j = $n; // 去除已到最后的项 $arr[$i] = array_slice($tmp, 0, $n, true); break; } } unset($tmp); }else{ // 将当前使用数组当前指针指向的值加入到组合数组 $arr[$i][] = current($args[$j]); next($args[$j]);// 当前使用数组指针前移一位 ++$j; // 当前使用数组下标+1 } } unset($args); return $arr;}

  1. function my_arr_combine(){
  2. $args = func_get_args();
  3. $final = array_shift($args);
  4. while($f = array_shift($args))
  5. {
  6. $r = array();
  7. foreach($final as $v)
  8. {
  9. foreach($f as $v2)
  10. {
  11. $r[] = array_merge(is_array($v)?$v:array($v),array($v2));
  12. }
  13. }
  14. $final = $r;
  15. }
  16. return $final;}$arr1 = array(1, 2, 3, 4);$arr2 = array(10, 20, 30, 40);$arr3 = array(100, 200, 300, 400);$data = array($arr1,$arr2,$arr3);echo "<pre class="layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li>";print_r(call_user_func_array('my_arr_combine', $data));</li></ol></pre> <p></p> <p class="sougouAnswer"> 不现丑了,收藏了再说。 </p> <p class="sougouAnswer"> </p><pre class="sycode layui-box layui-code-view layui-code-notepad" name="code"><ol class="layui-code-ol"><li>function my_arr_combine(){</li><li>$args = func_get_args();</li><li>$final = array_shift($args);</li><li>while($f = array_shift($args))</li><li>{</li><li>$r = array();</li><li>foreach($final as $v)</li><li>{</li><li>foreach($f as $v2)</li><li>{</li><li>$r[] = array_merge(is_array($v)?$v:array($v),array($v2));</li><li>}</li><li>}</li><li>$final = $r;</li><li>}</li><li>return $final;}$arr1 = array(1, 2, 3, 4);$arr2 = array(10, 20, 30, 40);$arr3 = array(100, 200, 300, 400);$data = array($arr1,$arr2,$arr3);echo "<pre class="layui-box layui-code-view layui-code-notepad"><ol class="layui-code-ol"><li>";print_r(call_user_func_array('my_arr_combine', $data));</li></ol></pre> <br> 这个简单明了 </li></ol></pre>

人气教程排行