一个全排列算法题的Java实现_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 一个全排列算法题的Java实现

一个全排列算法题的Java实现

 2013/12/16 19:09:06  Stream.Town  程序员俱乐部  我要评论(0)
  • 摘要:今天在上网时偶然遇到一个算法问题,原文在这里:http://blog.csdn.net/mdj_bj/article/details/7792223。题目是用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。看了题后没看答案直接开始动工,本来就是一个比较简单的全排列问题,算法自己也立即想了出来,就是不断在排列好的序列中插入新的元素。可貌似自己很久没写过这些算法题了
  • 标签:实现 Java 一个 算法
  今天在上网时偶然遇到一个算法问题,原文在这里:http://blog.csdn.net/mdj_bj/article/details/7792223。
题目是用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。
 
  看了题后没看答案直接开始动工,本来就是一个比较简单的全排列问题,算法自己也立即想了出来,就是不断在排列好的序列中插入新的元素。可貌似自己很久没写过这些算法题了,具体实现起来竟然花了好长时间,中间几次明明知道思路可就是不知道怎么转化为代码 。不过还好最后终于搞定,有了如下代码:
 
class="java">package com.tc.test;

import java.util.Arrays;

public class MTest {
	private char list[] = new char[]{'1', '2', '2', '3', '4', '5'};
	private int total = list.length;
	
	
	public static void main(String[] args) {
		long l1 = System.currentTimeMillis();
		new MTest().test();
		long l2 = System.currentTimeMillis();
		System.out.println("time:" + (l2 - l1) + "ms");
	}


	
	private void test() {
		printInOrder(new char[list.length], 0);
	}
	
	private void printInOrder(char[] current,  int fill) {
		if (fill == total) {
			print(current);
			return;
		}
		char a = list[fill];
		for (int i = 0; i < total; i++) {
			if (current[i] == 0) {
				char[] tmp = Arrays.copyOf(current, total);
				tmp[i] = a;
				printInOrder(tmp, fill + 1);
			}
		}
	}
	
	private void print(char[] array) {
		String line = new String(array);

		if (line.charAt(2) == '4' || line.indexOf("35") != -1 || 
				line.indexOf("53") != -1) {
			return;
		}
		System.out.println(line);
	}
}



弄完自以为大功告成,和原文里的算法做了一下对比,结果发现上面算法的结果比原文中的结果数量多了一倍,仔细一想,原来忽略了两个2造成的影响,可是木已成舟,想不出方法从根源解决,只能在最后过滤一下了,于是乎,最终的成品变成了下面这个样子:
package com.tc.test;

import java.util.Arrays;
import java.util.BitSet;

public class MTest {
	private char list[] = new char[]{'1', '2', '2', '3', '4', '5'};
	private int total = list.length;
	private BitSet state = new BitSet(543222);
	
	public static void main(String[] args) {
		long l1 = System.currentTimeMillis();
		new MTest().test();
		long l2 = System.currentTimeMillis();
		System.out.println("time:" + (l2 - l1) + "ms");
	}


	
	private void test() {
		printInOrder(new char[list.length], 0);
	}
	
	private void printInOrder(char[] current,  int fill) {
		if (fill == total) {
			print(current);
			return;
		}
		char a = list[fill];
		for (int i = 0; i < total; i++) {
			if (current[i] == 0) {
				char[] tmp = Arrays.copyOf(current, total);
				tmp[i] = a;
				printInOrder(tmp, fill + 1);
			}
		}
	}
	
	private void print(char[] array) {
		String line = new String(array);
		int n = Integer.parseInt(line);
		if (state.get(n)) {
			return;
		}
		state.set(n);
		if (line.charAt(2) == '4' || line.indexOf("35") != -1 
				|| line.indexOf("53") != -1) {
			return;
		}
		System.out.println(line);
	}
}


和原文中的算法重新对比,完全一致,而且性能上还有20%左右的提升,不过缺点是要开一个近100K的BitSet。
发表评论
用户名: 匿名