package com.towel.cfg;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ProgressiveString {
private List<CharInterval> charsIntervals;
private int charIntervalIndex;
private int minChar;
private int maxChar;
private char[] string;
public ProgressiveString(CharInterval... charIntervals) {
this("", charIntervals);
}
public ProgressiveString(String original, CharInterval... charIntervals) {
if (charIntervals.length == 0)
throw new RuntimeException("CharIntervals can't be null!");
string = original.toCharArray();
charsIntervals = Arrays.asList(charIntervals);
Collections.sort(charsIntervals);
charIntervalIndex = 0;
minChar = (int) charsIntervals.get(0).first;
maxChar = (int) charsIntervals.get(charsIntervals.size() - 1).last;
}
private char[] copyChars(int start, char[] old) {
char[] str = new char[start + old.length];
for (int i = 0; i < old.length; i++)
str[start + i] = old[i];
return str;
}
public void increase() {
char[] str = string.clone();
for (int i = str.length - 1; i >= 0; i--) {
IncreaseResult result = tryIncrease(str[i]);
str[i] = result.newChar;
if (result.result == IncreaseResult.INCREASED)
break;
if (result.result == IncreaseResult.DECREASED) {
if (i - 1 == -1) {
str = copyChars(1, str);
str[0] = (char) minChar;
break;
}
}
}
string = str.clone();
}
private IncreaseResult tryIncrease(char c) {
if (((int) c) == maxChar) {
charIntervalIndex = 0;
return new IncreaseResult((char) minChar, IncreaseResult.DECREASED);
} else
return new IncreaseResult(nextChar(c), IncreaseResult.INCREASED);
}
private char nextChar(char c) {
int i = (int) c;
if (i == charsIntervals.get(charIntervalIndex).last) {
charIntervalIndex++;
return (char) charsIntervals.get(charIntervalIndex).first;
}
return (char) (((int) c) + 1);
}
@Override
public String toString() {
return new String(string);
}
public static void main(String[] args) {
ProgressiveString str = new ProgressiveString(
String.valueOf((char) 33), new CharInterval('a', 'm'), new CharInterval('n', 'z'));
// JFrame frame = new JFrame("MutableString");
// JLabel label = new JLabel(" ");
// frame.add(label);
// frame.pack();
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setLocationRelativeTo(null);
// frame.setVisible(true);
int loops = 2500000;
for (int i = 0; i < loops; i++, str.increase(), System.out.println(str))
;
}
public static class CharInterval implements Comparable<CharInterval> {
protected int first;
protected int last;
public CharInterval(int first, int last) {
this.first = first;
this.last = last;
}
public boolean canIncrease(char character) {
int i = (int) character;
return i >= first && i <= last;
}
@Override
public int compareTo(CharInterval arg0) {
if (first < arg0.first)
return -1;
if (first > arg0.first)
return 1;
return 0;
}
}
private class IncreaseResult {
protected char newChar;
protected int result;
public IncreaseResult(char newC, int result) {
newChar = newC;
this.result = result;
}
protected static final int INCREASED = 0;
protected static final int DECREASED = 1;
}
}