求一排列算法

qidizi 2014-02-28 05:33:47


如图结构,a-d各为一列,称之y轴(+y方向),a1,b1,c1,d1为x轴(+x方向);
数字1,2,3...可以称为行,数字叫行号,
字母abcd..称之为列,叫列名
排列要求:
有效元素个数:一组排列,元素最少时是一个,如[a1],元素个数最多时是列的个数个如,[a1,b2,c1,d3];
有效排列:同列名的某元素可以与其它列(或多列)中的任一个元素结合,但一个排列中,不允许同列名的元素出现,也就是排列时,只允许在一个列取一个元素;
有序排列:向右结合即可,如a1b1与b1a1是相同排列,可以说是组合弃用向左结合集.
排列出现顺序:元素最多->元素个数相同时先最左边元素结合再右边,先行号小结合再行号大的结合,也就是先多元素,后少元素,同元素时,从左到右,从下到上;
代码实现时,请尝试不需要按组合后的左右下上的大小值来比较排序,人工在代码实现时控制出现顺序?

如有数据
[
['a1','a2']
,['b1','b2']
]

出现顺序

a1 b1
a2 b1
a1 b2
a2 b2

以上组合可以看到第一个元素是变的,后面元素固定,第一个元素变完再变后面

a1
a2
b1
b2

以上是全部组合.
谢谢


...全文
220 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangshaolongjj 2014-02-28
  • 打赏
  • 举报
回复
mark it
qidizi 2014-02-28
  • 打赏
  • 举报
回复
哦,谢谢补充的解释,我理解理解,没看过算法之类的书.
qidizi 2014-02-28
  • 打赏
  • 举报
回复
c的n人就是强,从来没用过~之类的位运算.
baihacker 2014-02-28
  • 打赏
  • 举报
回复
算法1: 给定集合,枚举元素个数为size的集合,主要是位操作上的技巧。 算法2: 在指定列的情况下,每个列选的元素的个数也知道,于是所有组合的个数是cnt[col[0]] * cnt[col[1]] ... 其中col[i]是选择的第i列。 换个角度思考,如果每个列的元素是10,那么每个组合和一个十进制数对应。 每个列元素个数不一定是10,只是变了进制而已,每一位上的进制不同,于是用temp来表示对应位上的权。 然后从小枚举所有的数,可以反向求出来每一位上的权,进而求出对应的元素。
qidizi 2014-02-28
  • 打赏
  • 举报
回复
修改后的代码,感觉应该是正确的 <script type="text/javascript"> function com(data) { var N = data.length;//列个数 var store = []; var temp = []; for (var size = N; size >= 1; --size) for (var mask = (1 << size) - 1; mask < 1 << N;) { var total = 1; for (var i = 0; i < N; ++i) if (mask & 1 << i) { temp[i] = total; total *= data[i].length; } for (var id = 0; id < total; ++id) { var s = []; for (var j = 0; j < N; ++j) if (mask & 1 << j) { var v = (id - id % temp[j]) / temp[j] % data[j].length; s.push(data[j][v]); } store.push(s); } var x = mask & - mask; var y = mask + x; mask = ((mask & ~y) / x >> 1) | y; } return store; } var data = [ ["A1",'A2','A3'] ,["B1","B2"] ,["C1","C2"] ,['d1'] ,['e1','e2','e3'] ]; document.write(com(data).join('<br />')); </script>
qidizi 2014-02-28
  • 打赏
  • 举报
回复
看了一下你回复的帖子,算法方面感觉很强大呀.
qidizi 2014-02-28
  • 打赏
  • 举报
回复
不错,很强, 测试了一下,结果是正确的,我正在把输入的数据结构改成 var data = [ ["A1",'A2'] ,["B1","B2"] ,["C1","C2"] ]; 看来你也会js, 我的输入数据如a1是一个数据来的,没有拆开a与1这样的存放,只是在看似行,列结构而已, 担心一会我没搞明白,需要再请教你,一会再二个帖子结分给你.呵呵.
baihacker 2014-02-28
  • 打赏
  • 举报
回复
<script>
	var N = 4;
	var cnt = [4, 2, 5, 3];
	var temp = [0, 0, 0, 0];
	var label = ['a', 'b', 'c', 'd'];
	for (var size = N; size >= 1; --size)
	for (var mask = (1 << size) - 1; mask < 1 << N;)
	{
		var total = 1;
		for (var i = 0; i < N; ++i)
		if (mask & 1 << i)
		{
			temp[i] = total;
			total *= cnt[i];
		}
		for (var id = 0; id < total; ++id)
		{
			var s = "";
			for (var j = 0; j < N; ++j)
			if (mask & 1 << j)
			{
				var v = (id - id % temp[j]) / temp[j] % cnt[j];
				s = s + label[j];
				s = s + (v + 1) + " ";
			}
			s = s + "<br/>";
			document.write(s);
		}
		var x = mask & - mask;
		var y = mask + x;
		mask = ((mask & ~y) / x >> 1) | y;
	}
</script>
qidizi 2014-02-28
  • 打赏
  • 举报
回复
出来只有3个元素的组合?小于列数的n个元素的组合没出来,且后面顺序是组合后面的c在变,不是a首先变,如正确的是 a1 b1 c1 a2 b1 c1 现在结果是 a1 b1 c1 a1 b1 c2 a1 b1 c3 这样它就变成了最右边的列组合最优先出现了,而不是最左边.
zhjdg 2014-02-28
  • 打赏
  • 举报
回复
var a=[['a1','a2'],['b1','b2','b3','b4'],['c1','c2','c3']];
var r = [];
var i =0;
var a_len = a.length;

for(; i<a_len; i++) {
    len = r.length;
    for(v in a[i]) r.push([a[i][v]]);
    for(j=0; j<len; j++) {
      for(v in a[i]) 
        r.push(r[j].concat(a[i][v]));
    }
}

var f = [];
i=0;
for(;i<r.length;i++){
	if(r[i].length == a_len){
		f.push(r[i]);
	}
}
var $a = f;
qidizi 2014-02-28
  • 打赏
  • 举报
回复
如果n列呢?这样处理肯定不行.
  • 打赏
  • 举报
回复
是否如此?
<script>
	var arr1=['a1','a1','a2'];
	var arr2=['b1','b1','b2'];
	alert(get(arr1,arr2));//[[a1,b1],[a1,b2],[a2,b1],[a2,b2]]
	
	function get(arr1,arr2)
	{
		var arr=[];
		
		if(arr1.length<arr2.length)
		{
			var o=arr1;
			arr1=arr2;
			arr2=o;
		}
			
		arr1=checkArr(arr1);
		arr2=checkArr(arr2);
		for(var i=0;i<arr1.length;i++)
		{
			for(var j=0;j<arr2.length;j++)
			{
				var temp=[];
				temp.push(arr1[i],arr2[j]);
				arr.push(temp);
			}
		}
		return arr;
	}
	function checkArr(arr)//数组去重
	{
		var json={};
		var temp=[];
		for(var i=0;i<arr.length;i++)
		{
			if(!json[arr[i]])
			{
				temp.push(arr[i]);
				json[arr[i]]=1;
			}
		}
		return temp;
	}
</script>
别闹腰不好 2014-02-28
  • 打赏
  • 举报
回复
写作文呢

87,907

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧