我正在制作一个优化脚本的工具,现在我想将其中的所有名称压缩到最小。我为它启动了这个函数,但不知怎么的,它在长度超过2后就停止了。有更简单的方法吗?我只需要一个模式,生成一个字符串从a -> z开始,然后aa -> az ba -> bz等等。
public String getToken() {
String result = ""; int i = 0;
while(i < length){
result = result + charmap.substring(positions[i], positions[i]+1);
positions[length]++;
if (positions[current] >= charmap.length()){
positions[current] = 0;
if ( current < 1 ) {
current++;length++;
}else{
int i2 = current-1;
while( i2 > -1 ){
positions[i2]++;
if(positions[i2] < charmap.length()){
break;
}else if( i2 > 0 ){
positions[i2] = 0;
}else{
positions[i2] = 0;
length++;current++;
}
i2--;
}
}
}
i++;
}
return result;
}
不像其他问题!!我不只是想增加一个整数,长度增加太多了
我用过一个
public class AsciiID {
private static final String alphabet=
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int currentId;
public String nextId() {
int id = currentId++;
StringBuilder b = new StringBuilder();
do {
b.append(alphabet.charAt(id % alphabet.length()));
} while((id /=alphabet.length()) != 0);
return b.toString();
}
}
我将使用基数为36或64(取决于大小写敏感性)的库,并使用整数运行它,在输出之前,将整数转换为基数为36/64的数字。您可以根据顺序来考虑,这更容易,并且输出值由可信库处理。
您可以使用:
Integer.toString(i++, Character.MAX_RADIX)
base36。它不会像Base64那样被大大压缩,但是你有一个一行的实现。
您可以搜索一些可以操作任意基数的数的库,例如27、37或更多。然后将该数字输出为字母数字字符串(类似于HEX,但使用a-zA-Z0-9)。
让我们假设我们只能输出ASCII(对于unicode这个问题得到…复杂):快速查看一下,它的可打印字符在[32126]范围内。因此,为了最有效地表示这个问题,我们必须对给定的94进制整数进行编码,并对生成的任何char加32。
你是怎么做到的?查看Sun在Integer.toString()
中是如何做到的,并相应地进行调整。这可能比必要的要复杂,想想如何把一个数转换成以2为基数。最简单的形式就是一个循环,只有一个除法和模数
在您的工具中,您需要创建一个字典,它将包含每个唯一字符串和字符串本身的唯一整数id。当向字典中添加字符串时,为每个新添加的唯一字符串增加给定的id。一旦字典完成,您可以简单地将id转换为String
,使用如下所示:
static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static final int CHARS_LENGTH = CHARS.length();
public String convert(int id) {
StringBuilder sb = new StringBuilder();
do {
sb.append(CHARS.charAt(id % CHARS_LENGTH));
id = id / CHARS_LENGTH;
} while(id != 0);
return sb.toString();
}
此函数生成第n个双射数(第0个除外)。这是最理想的编码。(第0个将是空字符串。)
如果有10个可能的字符,0
- 9
,按顺序生成:
- 10个长度1的字符串,从"0"到"9"
- 10*10个长度2的字符串,从"00"到"99"
- 10*10*10个长度3的字符串,从"000"到"999"
- 等。
示例使用了93个字符,因为我刚好需要这些字符用于Json。
private static final char[] ALLOWED_CHARS =
" !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
.toCharArray();
private static final AtomicInteger uniqueIdCounter = new AtomicInteger();
public static String getToken() {
int id = uniqueIdCounter.getAndIncrement();
return toBijectiveNumber(id, ALLOWED_CHARS);
}
public static String toBijectiveNumber(int id, char[] allowedChars) {
assert id >= 0;
StringBuilder sb = new StringBuilder(8);
int divisor = 1;
int length = 1;
while (id >= divisor * allowedChars.length) {
divisor *= allowedChars.length;
length++;
id -= divisor;
}
for (int i = 0; i < length; i++) {
sb.append(allowedChars[(id / divisor) % allowedChars.length]);
divisor /= allowedChars.length;
}
return sb.toString();
}