package org.quickbundle.util.numeral; /** * 实现一个可定制的X进制数字体系,步长至少2位,最长不限,可表示极大的数 * 默认是36进制,步长3位,每个父节点下最多有46656个兄弟子节点 */ public class RmBaseXNumeral { //配置类的对象 protected RmNumeralConfig config = null; //冗余RmBaseXConfig的chars值,是一个引用对象 private char[] chars = null; /** * 存储值的核心变量 */ private String value; /** * 内部的构造函数 * @param config_ */ protected RmBaseXNumeral(RmNumeralConfig config_) { if(config_ != null) { this.config = config_; } else { this.config = RmNumeralConfig.getDefaultConfig(); } chars = config.getChars(); } /** * 通过字符串构建 * @param config_ * @param value_ */ public RmBaseXNumeral(RmNumeralConfig config_, String value_) { this(config_); if(value_ == null || value_.length() == 0) { value_ = config.getMinValue(); } if(value_.length() == 1) { throw new RuntimeException("must 2 digit at least!"); } if(value_.matches(".*[^" + String.valueOf(chars) + "].*")) { throw new RuntimeException("valid char only include:" + String.valueOf(chars)); } this.value = value_; } /** * 通过字符串构建 * @param value_ */ public RmBaseXNumeral(String value_) { this(null, value_); } /** * 通过long构建 * @param config_ * @param lValue */ public RmBaseXNumeral(RmNumeralConfig config_, long lValue) { this(config_); if(lValue < 0) { throw new RuntimeException("can't construct negative long number!"); } this.value = long2String(lValue); } /** * 通过long构建 * @param lValue */ public RmBaseXNumeral(long lValue) { this(null, lValue); } /** * 返回下一个值,对象本身不改变 * @return */ public String getNext() { return getNext(1)[0]; } /** * 高性能的批量返回下一个值,对象本身不改变 * @param len * @return */ public String[] getNext(int len) { if(len == 0) { return new String[0]; } else if(len < 0) { throw new RuntimeException("can't getNext for negative number!"); } char[][] result = new char[len][value.length()]; long[][] aCarry = new long[value.length()-1][3]; //进位数,进位前增长了几位 for(int i=0; i<aCarry.length; i++) { long hex = 1L; for(int k=0; k<(aCarry.length-i-1); k++) { hex *= chars.length; } aCarry[i][2] = hex; } { //个位数 int indexLast = value.length()-1; //个位数的位置 int charPos = pos(value.charAt(indexLast)); //起始位置 for(int j=0; j<len; j++) { if(charPos == chars.length-1) { aCarry[indexLast-1][0] ++; //上一位进1位 charPos = 0; //退到首位 } else { if(aCarry[indexLast-1][0] == 0) { aCarry[indexLast-1][1] ++; //个位数增长1位 } charPos ++; } result[j][indexLast] = chars[charPos]; } } for(int i=0; i<value.length()-1; i++) { int digitPos = value.length()-2-i; //当前处理的位数 int charPos = pos(value.charAt(digitPos)); //起始位置 for(int j=0; j<len; j++) { if(aCarry[digitPos][1] > 0) { //消费后1位的不进位增长 aCarry[digitPos][1] --; if(digitPos > 0 && aCarry[digitPos-1][0] == 0) { aCarry[digitPos-1][1] ++; //上一位增长1位 } } else if(aCarry[digitPos][0] > 0){ //消费后1位的进位 if(charPos == chars.length-1) { if(digitPos > 0) { aCarry[digitPos-1][0] ++; //上一位进1位 } charPos = 0; //退到首位 } else { if(digitPos > 0 && aCarry[digitPos-1][0] == 0) { aCarry[digitPos-1][1] ++; //上一位增长1位 } charPos ++; } aCarry[digitPos][0] --; aCarry[digitPos][1] += (chars.length * aCarry[digitPos][2]) - 1; } result[j][digitPos] = chars[charPos]; //消费完毕,原样复制 } } String[] finalResult = new String[len]; for(int i=0; i<len; i++) { finalResult[i] = new String(result[i]); } return finalResult; } //long转化为62进制字符串格式 private String long2String(long lValue) { char[] cs = new char[config.getCharLength()]; long newValue = lValue; for(int i=0; i<cs.length; i++) { long thisDigit = 1L; for(int k=0; k<cs.length-i-1; k++) { thisDigit *= chars.length; } int pos = (int)(newValue / thisDigit); cs[i] = chars[pos]; newValue = newValue % thisDigit; } return String.valueOf(cs); } /** * long形式的值展现 * @return */ public long longValue() { long result = 0L; result += pos(value.charAt(value.length()-1)); for(int i=0; i<value.length()-1; i++) { long thisDigit = pos(value.charAt(i)); for(int k=0; k<value.length()-i-1; k++) { thisDigit *= chars.length; } result += thisDigit; } return result; } /** * 执行加法运算,会改变对象,返回字符串格式 * @param len * @return */ public String add(long addend) { long lValue = longValue(); this.value = long2String(lValue + addend); return this.value; } /** * 执行减法运算,会改变对象,返回字符串格式 * @param len * @return */ public String subtract(long subtrahend) { long lValue = longValue(); this.value = long2String(lValue - subtrahend); return this.value; } //取位置 private int pos(char c) { //开始二分法查找 int start=0, end=chars.length-1; while(end > start + 1) { int middle = (int)Math.floor((start+end)/2.0); if(chars[middle] == c) { start = middle; break; } else if(chars[middle] > c) { end = middle; } else { start = middle; } } if(chars[start] != c) { if(chars[end] == c) { start = end; } else { throw new RuntimeException("not find '" + c + "' in: " + String.valueOf(chars)); } } return start; } @Override public String toString() { return value; } public String toStringSimple() { return value.replaceFirst("^" + chars[0] + "+", ""); } /** * @return 配置实例 */ public RmNumeralConfig getConfig() { return config; } }