package jef.tools.string;
import java.util.Iterator;
import jef.tools.StringUtils;
import org.apache.commons.lang.ArrayUtils;
/**
* 字符串枚举器
* 居然字符串是能比较大小的,那么字符串显然也是可以枚举的。
* @author jiyi
*
*/
public class StringIterator implements Iterator<String> {
private static char[] TABLE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
AnyNumeral endValue;
AnyNumeral current;
/**
* 构造
* @param start 开始字符串
* @param end 结尾字符串
* @param maxLen 字符串最大长度
* @param TABLE 字符码表
*/
public StringIterator(String start, String end, int maxLen, char[] TABLE) {
this.current = new AnyNumeral(maxLen, TABLE);
this.endValue= new AnyNumeral(maxLen, TABLE);
current.setValue(start);
endValue.setValue(end);
current.decreament();
endValue.decreament();
}
/**
*
* @param start
* @param end
* @param maxLen
* @param TABLE
* @param includeStart 含头
* @param includeEnd 含尾
*/
public StringIterator(String start, String end, int maxLen, char[] TABLE,boolean includeStart,boolean includeEnd) {
this.current = new AnyNumeral(maxLen, TABLE);
this.endValue= new AnyNumeral(maxLen, TABLE);
if(start==null){
current.setValue(String.valueOf(TABLE[0]));
// includeStart=true;
}else{
current.setValue(start);
}
if(end==null){
endValue.setValue(StringUtils.repeat(TABLE[TABLE.length-1], maxLen));
includeEnd=true;
}else{
endValue.setValue(end);
}
if(includeStart)
current.decreament();
if(!includeEnd)
endValue.decreament();
}
public StringIterator(String start, String end, int maxLen) {
this(start,end,maxLen,TABLE);
}
public boolean hasNext() {
return current.compareTo(endValue)<0;
}
public String next() {
return current.increament().getValue();
}
public String previous() {
return current.decreament().getValue();
}
public void remove() {
throw new UnsupportedOperationException();
}
/**
* 用于实现字符串遍历的核心算法
* 任意进制数算法
*
* @author jiyi
*/
static class AnyNumeral implements Comparable<AnyNumeral> {
private int maxLen;//位数
private char[] TABLE;//字符表
private byte[] data;
private byte numeral;
private int strLen;
@Override
public String toString() {
return getValue();
}
public AnyNumeral(int num,char[] TABLE) {
this.maxLen = num;
this.TABLE=TABLE;
this.numeral=(byte)TABLE.length;
this.data = new byte[num];
}
public void setValue(String text) {
for (int i = 0; i < maxLen; i++) {
if (i < text.length()) {
char c = text.charAt(i);
int num = ArrayUtils.indexOf(TABLE, c);
if (num < 0)
num = 0;
data[i] = (byte)num;
}else{
data[i] = -1;
}
}
strLen=text.length();
}
public String getValue(){
StringBuilder sb=new StringBuilder(maxLen);
for(int i=0;i<maxLen;i++){
int code=data[i];
if(code>=0){
sb.append(TABLE[code]);
}else{
break;
}
}
return sb.toString();
}
public AnyNumeral increament() {
if(strLen<maxLen){
data[strLen++]++;
}else{
increament(1);
}
return this;
}
private void increament(int i) {
if(i<=maxLen){
int value=++data[maxLen-i];
if(value>=numeral){//进位
data[maxLen-i]=-1;
increament(i+1);
strLen--;
}
}else{
throw new IllegalArgumentException("Exceed max limit.");
}
}
public AnyNumeral decreament() {
decreament(1);
return this;
}
private void decreament(int i) {
if(i<=maxLen){
if(data[maxLen-i]==-1){
int size=strLen;
decreament(i+1);
if(strLen==size){//如果未采用了减位的方式来递减
while(strLen<maxLen){
data[strLen++]=(byte)(numeral-1);
}
}
return;
}
int v=--data[maxLen-i];
if(v==-1){
strLen--;
}
}else{
throw new IllegalArgumentException("Exceed min limit.");
}
}
public int compareTo(AnyNumeral o) {
for(int i=0;i<maxLen;i++){
if(data[i]<o.data[i]){
return -1;
}else if(data[i]>o.data[i]){
return 1;
}
}
return 0;
}
}
public static void main(String[] args) {
String a = "18";
String b = "30";
StringIterator iter = new StringIterator(a, b,2, CharUtils.ALPHA_NUM_UNDERLINE);
int count=0;
long start=System.currentTimeMillis();
while (iter.hasNext()) {
System.out.println(iter.next());
count++;
}
long time=System.currentTimeMillis()-start;
System.out.println("-------------------");
System.out.println(time);
System.out.println("Total:"+count);
}
}