(真)n选m排列算法next_permutation() 非递归版本

/**
 *@auther 皇阿玛
 *2019/9/16 13:51
 */

package courseOne;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;


class Permutation{//递归方法,要找一个非递归的方法
	int total;
	static int count=0;
//	private int[] people;
	public Permutation(){}
	public Permutation(int total,int SelectPeople){
//		this.people = new int[SelectPeople];
		this.total = total;
	}
	public boolean next(List<Integer> lis,int start){
		if(start >= lis.size() ){
			System.out.println(lis);
			count++;
			return true;
		}
		for(int i=1;i<=total;i++){
			if( !lis.contains(i) ){
				lis.set(start, i);
			}else{
				continue;
			}
			next(lis,start+1);
			lis.set(start, -1);
		}
		return true;
	}
	public boolean next2(List<Integer> lis){//非递归写出来
		int flag = 0;//用来判断初始list是否全为0,则需要赋初值1,2,3...
		int ChangeFlag = 0;//用来判断是否已经对list进行更新了,若已更新,则直接退出并返回true
		for(int i=0;i<lis.size();i++){
			flag += lis.get(i);
		}
		if(flag == 0){//初始化
			for(int j=0;j<lis.size();j++){
				lis.set(j, j); //lis.set(index, element)
			}
			ChangeFlag = 1;
		}else{
			for(int k=lis.size()-1;k>=0;k--){
//				System.out.println("1.k = "+k);/////////////////////////////
				if(!IsMaxOrNot(lis,k) && ChangeFlag == 0){//最后一位不是最大值的话,就进行最小增值
					if( LittleIncrease(lis,k) )
						ChangeFlag = 1;
					//break;
					//若最后一位是最大值,则  k 进入下一层for循环,即把lis中的搜索位置前移
					//若更新的位置k不是最后一位,则需要对k位之后的数据进行从小到大更新!
					if(1 == ChangeFlag ){//如果最小更新的元素位置是k的话=>&& k < lis.size()
//						System.out.println("I'm complemening!!!,k = "+k+" lis = "+lis);
						Complement(lis,k);//对k之后的元素进行按顺序补全
					}
					break;
				}	
			}
		}
		if(1 == ChangeFlag)
			return true;
		else
			return false;
	}
	
	public boolean IsMaxOrNot(List<Integer> lis,int loc){//loc从0开始计数
		int[] tem = new int[total];//初值为0;
		Arrays.fill(tem, 0);	    //对数组用某个数进行填充
		int flag = 1;				//判断标志,默认是最大值,则flag=1,若不是最大值,则令flag=0;
		
		for(int i=0;i<lis.size() && i<loc;i++){//对loc之前&&已用过的 元素进行标记
			tem[lis.get(i)] = 1;
		}
		for(int j=0;j<total;j++){  //未用过的元素中去比较查找是否有更大的元素
			if(tem[j] != 1 && j>lis.get(loc))//数值 j 没用过,而且 j 比lis第loc位的数值要大。
				flag = 0;		   //说明list.get(loc)不是最大值,还有更大的数值可选
		}
		if(0==flag) 
			return false;
		else
			return true;
	}
	public boolean LittleIncrease(List<Integer> lis,int loc){//当某个位置的数值不是最大值时,进行最小限度地增加
		int[] tem = new int[total];//初值为0;
		Arrays.fill(tem, 0);	    //对数组用某个数进行填充
		int flag = 0;				//判断标志,默认是最大值,则flag=1,若不是最大值,则令flag=0;
		
		for(int i=0;i<lis.size() && i<loc;i++){//对loc之前&&已用过的 元素进行标记
			tem[lis.get(i)] = 1;
		}
		for(int j=0;j<total;j++){  //未用过的元素中去比较查找是否有更大的元素
//			System.out.println("2.lis.get(loc) = "+lis.get(loc)+" loc = "+loc);
			if(tem[j] != 1 && j>lis.get(loc)){//数值 j 没用过,而且 j 比lis第loc位的数值要大。
				lis.set(loc, j);   //把loc位置的数值增加为j;!!!!!!!!!!!!
				flag = 1;		   //完成增值工作
//				System.out.println("3.list = "+lis);
				break;
			}
		}
		if(0==flag){
//			System.out.println("false");
			return false;
		}
			
		else{
//			System.out.println("true");
			return true;
		}
			
	}
	public boolean Complement(List<Integer> lis,int loc){//loc是中间更新的位置下标(index) <=> k
		//当处理完的最小增值位置不是在最后一位时,需要对 后面 元素进行补全,按照剩余元素,从小到大处理;当前的 loc 位置  不用改动 !!!!!
		int[] tem = new int[total];//初值为0;
		Arrays.fill(tem, 0);	    //对数组用某个数进行填充
		//int flag = 1;				//判断标志,
//		System.out.println("4.in Complement,loc = "+loc+", lis = "+lis);
		for(int i=0;i<=loc;i++){//对loc之前&&已用过的 元素进行标记(loc就是下标,直接带入index)  :i<lis.size() && 
			tem[lis.get(i)] = 1;				//这里loc要记得取等号
		}
		
		for(int j=loc+1;j<lis.size();j++){//j:每个待修正的位置坐标!!!对loc之后的元素进行重新洗牌,坐标从(loc+1)开始走
			int ChangeFlag = 0;//修补过程,已进行到的 位置 下标!!!
			for(int k=0;k<total && ChangeFlag == 0;k++){
				if(tem[k]!=1){
					lis.set(j, k);
					ChangeFlag = 1;
					//ChangeFlag++;
					tem[k] = 1;
//					System.out.println("5.lis = "+lis+", k = "+k+", loc = "+loc+", Changeflag="+ChangeFlag);
				}
			}
		}
		return true;
	}
	
}


public class PermutationExample {
	public static void main(String[] args){
		
		int sum = 0;
		int total = 5;
		int need = 3;// n <=> SelectPeople
		List<Integer> lis = new ArrayList<Integer>();
		List<String> lis2 = new ArrayList<String>();
//		lis2.add("q");
//		lis2.get(0);
//		System.out.println("ss");
		for(int i = 0 ; i < need;i++) {
			lis.add(0);
		}
		Permutation perm = new Permutation(total,need);
		
		
		while(perm.next2(lis)){
			System.out.println(lis);
			sum++;
		}
		System.out.println("The num of permutations is "+sum+" !!!");
//		while(sum>0){
//			perm.next2(lis);
//			System.out.println(lis);
//			sum--;
//		}
	}
}
		/**
		 * 
		 
		List<Integer> lis = new ArrayList<Integer>();
		for(int i = 0 ; i < need;i++) {
			lis.add(-1);
		}
		
		Permutation per = new Permutation(total,need);
		per.next(lis, 0);
//		int sum = 60;
//		while( sum>0 ){
//			per.next(lis, 0);
//			System.out.println(lis);
//			sum--;
//		}
		System.out.println("all of the number:"+per.count); 
		*/

 

上一篇:wordcloud:利用fontawesome字体绘制图标词云图


下一篇:矢量字体图标FontAwesome.WPF