码迷,mamicode.com
首页 > 编程语言 > 详细

可逆算法-实现按照 n进制的数字压缩

时间:2015-09-08 15:36:55      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:算法

import java.util.HashMap;
import java.util.Stack;
/*
 * 思路:
 * 传入一个字符串作为母串字典,根据母串位数定义进制。传入数值后,根据进制转化为字符串。
 * 使用:
 * 
 * public String escape(long[] targetPos) 传入n维数组,对应 n1*n2*...的数值,返回此数值对应的转义字符串。
 * public long[] unescape(String word) 传入字符串,返回此串生成时对应的 n 维数组
 * */


public class IdGenerator {
	private String words;
	private HashMap<Character, Integer> decs;
	private long[] layerCount;
	private int maxLength;
	private long startValue=-1;

	
	public IdGenerator(String words, long[] layerCount){	
			this.words = words;
			this.layerCount = layerCount;
			initData();
	}
	private String dec2word(long num, int wordsLength){
		Stack<Character> word = new Stack<Character>();
		
		int pos =0 ;
		while(num>0){
			pos = (int)((num%this.words.length()));
			
			Character c = new Character(this.words.charAt(pos));

			//			System.out.println("通过运算获得的对应字符-----------"+c.charValue());
			num = (long) Math.ceil(num/this.words.length());
//			System.out.println(c+"  "+pos+"   "+num+"  "+this.words.length());

			word.push(c);

		}
//		System.out.println("----"+wordsLength + "   " + word.size());

		if(wordsLength == 0){
			wordsLength = word.size();
		}
//		System.out.println(wordsLength+" - - - - - -"+word.size());
		while(wordsLength > word.size()){
			word.push(new Character(words.charAt(0)));
		}
		String result = "";
		while(!word.isEmpty()){
			Character c = (Character)word.pop();
			result = c.charValue()+result;
		}
//		System.out.println(result);
		return result;
	}
//	
//	function dec2word(num, wordsLength) {
//        var word = [];
//        while (num > 0) {
//            word.push(words[num % wordslen]);
//            num = Math.floor(num / wordslen);
//        }
//        console.log("------"+wordsLength,wordslen)
//        wordsLength = wordsLength || word.length;
//        while (wordsLength > word.length)
//            word.push(words[0]);
//
//        console.log("******"+word.join(‘‘))
//        return word.join(‘‘);
//    }

	
	private long word2dec(String word){
		long num = 0;
		char c = ‘a‘;
		for(int i = word.length() -1 ;i>=0;i--){
			num *= words.length();
//			System.out.println("before : "+num);
			c = word.charAt(i);
			Integer k = (Integer)this.decs.get(new Character(c));
			num += k.intValue();
//			System.out.println(c+"  "+k.intValue() +"----"+num+"  "+words.length());

		}
//		System.out.println("num : ---"+num);
		return num;
	}
	
	public long[] unescape(String word){
		if(word==null||word.length() != maxLength){
			return null;
		}
		long num = this.word2dec(word);
		long[] output = new long[layerCount.length];
//		int count = 0;
		for(int i = layerCount.length -1;i>=0;i--){
			output[i] = num%layerCount[i];
			num = (long) Math.floor(num/layerCount[i]);
//			count++;
		}
		return output;
	}
	private void printArray(long[] array){
		for(int i=0;i<array.length;i++){
			System.out.println(array[i]);
		}
	}
	public String escape(long[] targetPos) {
//		System.out.println("targetPos");
//		printArray(targetPos);
//		System.out.println("layerCount");
//		printArray(layerCount);
//		
		if (this.layerCount.length!=targetPos.length){
	        return null;
		}
		try{
			
		}catch(Exception ex){
			
		}
		long num = 0;
	    int len = this.layerCount.length;
	    for (int i = 0; i < len; i++) {
	    	if(targetPos[i]>=this.layerCount[i]){
	    		System.err.println("overflow number range of :"+(i+1)+" parameter!"); 
	    		return null;
	    	}
	    	num *= this.layerCount[i];
	        num += targetPos[i];
	    }
//	    System.out.println(num);
//	    System.out.println(maxLength);

	    return dec2word(num, maxLength);
	}
	
	private void initData(){
		decs = new HashMap<Character, Integer>();
		for(int i = layerCount.length-1;i>=0;i--){
			if(startValue<=0){
				startValue = layerCount[i];
			}else{
				startValue *= layerCount[i];
			}
		}
		this.maxLength = this.dec2word(startValue,0).length(); 
		for(int i=0;i<words.length();i++){
			decs.put(new Character(words.charAt(i)), new Integer(i));
		}
		
	}
}


使用实例:

public class Main {
	public static void main(String[] args) {
		long[] size = new long[]{10000000,10000000};//第一层个参数为总有多少个批次,第二层为每一批次有多少数量
		IdGenerator idGen = new IdGenerator("S38WqpOtRPbEVgQMNjZTuFk40L2Hr7zoAyaYDvlfUdJGcwx5nI6Cs1ih9meXKB",size);
//		idGen.initData();
		long[] targetPos = new long[]{111,2000191}; //第一层个参数为第几批次,第二层为序号			
		String result = idGen.escape(targetPos);//数字转字符串
		long[] list = idGen.unescape(result);//字符串转数字

		System.out.println(result);

		for(int j=0;j<list.length;j++){
			System.out.println(list[j]);
		}
		
	}

	
}


可逆算法-实现按照 n进制的数字压缩

标签:算法

原文地址:http://ericyu.blog.51cto.com/2320641/1692701

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!