为了账号安全,请及时绑定邮箱和手机立即绑定

n个数组排列组合

n个数组排列组合

千里① 2017-08-09 16:58:47
对这样的数组取n个元素进行排列组合[[3.5],[4.6,23],[5.25,13]]想要的结果:1、取两个排列的时候【3.5,4.6,】,【3.5,23】,【3.5,5.25】,【3.5,13】,【4.6,5.25】,【4.6,13】,【23,5.25】,【23,13】2、取三个排列的时候【3.5,4.6,5.25】,【3.5,4.6,13】,【3.5,23,5.25】,【3.5,23,13】
查看完整描述

1 回答

已采纳
?
最初__

TA贡献68条经验 获得超39个赞

第一次收到邀请回答。。不过今天才看到

代码我就用php写了,带注释,


这个题目一看排列组合,我能想到的就是  递归搜索了,以下仅为一种参考解法,并非最优


对这样的数组取n个元素进行排列组合[[3.5],[4.6,23],[5.25,13]],   我把这个问题拆分成2步,一是对这个二维数组 (简称 a)任取  n  个子一维数组组成一个新的二维数组 (简称 b),  然后对 b 进行任取 n 个元素的操作,这时就是对 b 中每一个子一维数组中任取一个元素,组在一起即为题解。


例:

    a = [[3.5],[4.6,23],[5.25,13]]

    n = 2


此时 b 有3个, 分别为

    b1 = [[3.5], [4.6,23]]

    b2 = [[3.5],  [5.25, 13]]

    b3 = [[4.6, 23], [5.25, 13]]

再对每个 b 中每一个子一维数组中任取一个元素, 组在一起即为题解


对 b1

     【3.5,4.6,】,【3.5,23】,

对 b2

    【3.5,5.25】,【3.5,13】,

对 b3

    【4.6,5.25】,【4.6,13】,【23,5.25】,【23,13】


一下是参考代码(2 步 都是用 递归做的) :

<?php

// 此函数作用:任取 a 中 n 个子一维数组 ,组成 b 
function aofn($a, $b, $n) {
         
        // 递归终止条件,每次递归 n - 1, 当 n 为 0 时说明以找到  n 个子一维数组
        //然后把组成的 b 作为第二步函数的参数传进去
	if($n == 0) {
		$c = array();
		// var_dump($b);
		test($b, $c, count($b));
		return ;
	}

	for($i = 0; $i < count($a); $i ++) {
	
	        // 每次取得子一维数组放到 b 中
		$b[] = $a[$i];
		
		//array_slice($a, $i+1) : 取 a 中索引从 $i+1 位置的数组到最后组成一个新数组
		//因为像 1,2 和 2,1这种是相等的,所有直接往后取
		aofn(array_slice($a, $i+1), $b, $n - 1);
		// 每次搜索完记得移除 b 上面添加的那个子数组,继续下一次搜索
		array_pop($b);
	}
}

// 注意一下两个函数的参数位置关系, 第一个函数中的 $b 变成了这里的 $a,
// 这里的 $b 是一个空一维数组 ; 
//此函数作用:再对每个 a 中每一个子一维数组中任取一个元素, 组在一起
function test($a, $b, $n) {

        // 这里终止条件跟上面函数差不多,每次找一个,找到 n 个终止,继续找下一轮
	if($n == 0) {
	        // 输出找到存起来的元素
		foreach($b as $k) {
			echo $k.' ';
		}
		echo "\n";
		return ;
	}
        
        //这里就是每次去一个子数组出来,b每次存子数组中的一个元素,递归完就全部取完了
	for($i = 0; $i < count($a[0]); $i ++) {
	        
	        //移除 a 的第一个子数组
		$arr = array_shift($a);
		$b[] = $arr[$i];
		
		test($a, $b, $n-1);
		
		// 每次搜索完记得移除 b 上面添加的那个子元素,继续下一次搜索
		array_pop($b);
		// 每次搜索完记得加入 a 上面移除的那个子数组(这个函数是添加到头部),
		//继续下一次搜索
		array_unshift($a, $arr);
	}
}

//代码没有写判断不合法输入,只要输入正常,输出是没问题的,以下是测试用例
//注意:因为是递归写的,相对费时,所以不能测试 较大的数据量

$a = array([3.5], [4.6, 23], [5.25, 13]);
$b = array();
$n = 2;

aofn($a, $b, $n);

    

查看完整回答
2 反对 回复 2017-08-14
  • 1 回答
  • 1 关注
  • 2320 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信