排列组合其实具体概念我记得好像是不能有重复,每次组合中每个数都必须全部用到而且只能用一次。看见有很多人都把问题简单化了,今天为了完成任务,写了一个能正确运行的“算法”,“算法”之所以打引号那是因为我觉得好的算法要求是效率高,开销低,这个下次再考虑吧。
- package com.pbj.mail;
- import java.util.HashSet;
- import java.util.Set;
- /**
- * 写一个序列的所有排列组合
- *
- * @remarks 首先,排列组合是不允许有重复的,所以使用Set集合进行保存,保存前使用contains方法进行判断
- * 大概思路:用一个一位数组保存新的序列,使用递归,每递归一次,就是确定新序列中的一个数。为了数之间不重复,采用了标记判断这个数是否被用过
- * 这个算法也只是临时解决一下问题,效率,性能方面有欠缺。日后再改进
- * @author SNOW 2013-2-21
- */
- public class MyMath {
- int[][] array = { { 1, 2, 3, 4, 5, 6 } //第一行是基数
- , { 0, 0, 0, 0, 0, 0 } }; // 第二行是标记,1表示已经占用,0表示空闲
- int[] store = new int[array[0].length]; // 临时保存新的序列
- static Set<String> set = new HashSet<String>(); // 这里注意Set集合是保存对象的,所以不能保存公共的对象进去,一定要是局部对象
- /**
- * 递归,每执行一次方法,确定一位数
- *
- * @param index
- */
- public void push(int index) { // index表示序列中第几位
- for (int i = 0; i < array[0].length; i++) {
- if (!check(i)) //判断i位置的数有没有被用了
- continue; //被用了就找下一个没用过的数
- store[index] = array[0][i]; //把这个数赋值给新序列的index位置
- // 把i设为”占用“
- array[1][i] = 1;
- if (index == array[0].length - 1) { //判断是不是已经到了新序列最后一个数
- if (!set.contains(store)) { // set集合中没有,那么就就添加进去
- set.add(store.toString()); // 添加进去
- print(); // 打印
- }
- } else
- push(index + 1);
- // 清除状态,对于这次使用的数应该把状态改回来,给下次用
- array[1][i] = 0;
- }
- }
- /**
- * 主方法
- *
- * @param args
- */
- public static void main(String[] args) {
- MyMath m = new MyMath();
- m.push(0);
- }
- /**
- * 打印
- */
- public void print() {
- for (int a : store) {
- System.out.print(a + " ");
- }
- System.out.println();
- }
- /**
- * 判断这个数字有没有被占用
- * @param i
- * @return true——为占用 false——占用
- */
- public boolean check(int i) {
- // 判断数组越界
- if (i < 0 || i > array[0].length) {
- return false;
- }
- if (array[1][i] == 0) {
- return true;
- } else
- return false;
- }
- }
下次有时间再改进改进
转载于:https://blog.51cto.com/liangxueming/1137237