尽可能短的唯一ID

时间:2011-09-26 18:52:00

标签: java optimization netbeans

我正在制作一个优化脚本的工具,现在我想将其中的所有名称压缩到最小。 我得到了它的功能,但是在超过长度2之后它会以某种方式出现错误并停止。 有更简单的方法吗?我只需要一个从a - >开始生成字符串的模式。然后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;
}

不解决其他问题!!我不想只增加一个整数,长度增加很多。

7 个答案:

答案 0 :(得分:1)

我将使用基数36或基数64(取决于区分大小写)库并使用整数运行它,在输出之前,将整数转换为基数36/64数。您可以根据顺序进行思考,这更容易,输出值由受信任的库处理。

答案 1 :(得分:1)

这是我用过的一个

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();
    }
}

答案 2 :(得分:0)

您可以搜索一些操作任何基数的数据库,例如27,37或更多。然后将该数字输出为字母数字字符串(如HEX,但使用a-zA-Z0-9)。

答案 3 :(得分:0)

您可以使用:

Integer.toString(i++, Character.MAX_RADIX)

它是base36。它不会像Base64那样大大压缩,但你有一个实现。

答案 4 :(得分:0)

好吧我们假设我们只能输出ASCII(对于unicode这个问题变得复杂):快速查看显示其可打印字符在[32,126]范围内。因此,为了最有效地表示这个问题,我们必须在base 94中对给定的整数进行编码,这样就可以将32添加到任何生成的char中。

你是怎么做到的?查看Sun如何在Integer.toString()中执行此操作并相应地进行调整。那么它可能比必要的更复杂 - 只要考虑如何将数字转换为基数2并进行调整。最简单的形式,基本上是一个分区和模数的循环。

答案 5 :(得分:0)

在你的工具中,你需要创建一个字典,它将包含每个唯一字符串和字符串本身的唯一整数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();
  }    

答案 6 :(得分:0)

此函数生成第N Bijective Number个(除了第0个)。这是有史以来最优化的编码。 (第0个是一个空字符串。)

如果有10个可能的字符0 - 9,则按顺序生成:

  • 长度 1 的10个字符串,来自&#34; 0&#34;到&#34; 9&#34;
  • 长度 2 的10 * 10个字符串,来自&#34; 00&#34;到&#34; 99&#34;
  • 10 * 10 * 10根长度 3 ,来自&#34; 000&#34;到&#34; 999&#34;

该示例使用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();
}