マルチ水仙数アルゴリズム

5738 ワード

マルチ水仙数アルゴリズム
1.再帰(使用時間16-20 s;書くのがとても便利で、とても爽やか):
import java.math.BigInteger;
import java.util.ArrayList;

/**
 *          4 :153,370,371,407;  
	         3 :1634,8208,9474;   
	         3 :54748,92727,93084;   
	         1 :548834;   
	         4 :1741725,4210818,9800817,9926315;   
	         3 :24678050,24678051,88593477 
 * @author Administrator
 *ps :  new BigInteger(),  BigInteger.valueof();       35    20 
 */
public class FlowerNumber_simple {
	private int size;
	private ArrayList resultLists;
	private int[] base_num_count;
	private BigInteger[] subResult;
	
	public FlowerNumber_simple(int size){
		this.size = size;
		resultLists = new ArrayList();
		base_num_count = new int[10];
		subResult = new BigInteger[10];
		
		/*for(int i=0;i<10;i++){
			subResult[i] = new BigInteger(i+"").pow(size);
		}*/
		for(int i = 0; i < 10; ++i){
			//subResult[i] = BigInteger.valueOf(i).pow(this.level);
			subResult[i] = BigInteger.ONE;
			for(int j = 0; j < size; ++j){
				subResult[i] = subResult[i].multiply(BigInteger.valueOf(i));
			}
		}
		
		
	}
	
	
	public static void main(String[] args) {
		FlowerNumber_simple fn = new FlowerNumber_simple(21);
		long start = System.currentTimeMillis();
		fn.backTracking(0, 0);
		for(BigInteger b : fn.resultLists){
			System.out.println(b);
		}
		long times = System.currentTimeMillis()-start;
		System.out.println(times/1000+" ");
	}
	
	private void backTracking(int level,int current_index){
		if(level>=size){
			getresult();
			return ;
		}
		for(int i=current_index;i < 10;i++){
			base_num_count[i] ++;
			backTracking(level+1, i);
			base_num_count[i] --;
		}
		
	}

	private void getresult() {
		
		BigInteger result = BigInteger.ZERO;
		for(int i=0;i<10;i++){
			if(base_num_count[i]!=0){
				//result = result.add(subResult[i].multiply(new BigInteger(base_num_count[i]+""))  );
				result = result.add(subResult[i].multiply(BigInteger.valueOf(base_num_count[i])));
			}
		}
		String result_str = result.toString();
		if(result_str.length()== size){
			int[] same_num_count = new int[10];
			for(int i =0 ;i

2.スタック遡及(使用時1 s-3 s;極速):
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;


/**
 *         
 * @author lixinji
 *         
*0.            。(21     ,          10s 30s  )
 * 1.      :       ,  0 9,1 9....9 9        。         ,         
 * 2.     :       ,     ,   ,        ,       ,          
 * 3.      :        ,                ,            ,  。(        2 9,                3 ,      )
 */
public class FlowerNumber {
	private int size; 			//  
	private  BigInteger MIN_CONSTANT; 	//     
	private  BigInteger MAX_CONSTANT;	//     
	private Hashtable ht;  //       , hashtable       
	private Set resultsets = new HashSet(); //      
	private int index;//  ,  9-index    
	private int[] base_num_count;		// base_num_count[index]            
	private int[] sum_num_count;		//sum_num_count[index]               
	private BigInteger[] totalResult;	//sum_num_count[index]              
	
	


	public FlowerNumber(int size) {
		this.size = size;
		int s = size<10?10:size;
		base_num_count = new int[s];
		sum_num_count = new int[s];
		totalResult = new BigInteger[s];
		ht = new Hashtable();
		
		for(int i=0;i<=s;i++){ //    ,      
			ht.put("n_"+i, new BigInteger(i+""));
		}
		for(int i=0;i<=10;i++){ //     size    
			ht.put("p_"+i, new BigInteger(i+"").pow(size));
		}
		MIN_CONSTANT=N(10).pow(size-1);
		MAX_CONSTANT=P(10).subtract(N(1));
	}
	private BigInteger N(int i){
		return ht.get("n_"+i);
	}
	private BigInteger P(int i){
		return ht.get("p_"+i);
	}
	
	public static void main(String[] args) {
		
		FlowerNumber fn =new FlowerNumber(21); //      
		int s = fn.MAX_CONSTANT.divide(fn.P(9)).intValue();//  P(9)   
		for(int i=0;i<=s;i++){
			fn.find(i);
		}
		BigInteger[] results =new BigInteger[fn.resultsets.size()];
		fn.resultsets.toArray(results);
		Arrays.sort(results);
		for(BigInteger bi : results){
			System.out.println(bi);
		}
		
	}
	//         ,        ,           ;   ,   。
	private boolean checkCombination(){
		BigInteger minVal = totalResult[index];
		BigInteger maxVal = totalResult[index].add(P(9-index).multiply(N(size-sum_num_count[index])));
		
		//         
		if(minVal.compareTo(MAX_CONSTANT)>0) return false;
		if(maxVal.compareTo(MIN_CONSTANT)<0) return false;
		String minStr = minVal.toString();
		String maxStr = maxVal.toString();
		
		char c;
		int sameCount[] = new int[10];
		for(int i=0;i 0)
					index --;
				else 
					return true;
			}
		}
		//        9,         1,      
		if(index >0){
			setValue(base_num_count[index]-1);
			return false;
		}else{
			return true;
		}
		
	}
	
	private boolean checkEnd(){
		for(int i=0;i<=9;i++){
			if(base_num_count[i] !=0)
				return false;
		}
		return true;
	}
	
	
}