缩小数字的好方法

时间:2012-10-16 09:40:41

标签: java c++ c algorithm

  

可能重复:
  Compress 21 Alphanumeric Characters in to 16 Bytes

我有8个号码

有没有办法将它转换为长度为4的字符串?

例如:

输入12345678

输出AB2D

转换应该能够准确转换回来。

我尝试将其转换为32 Hex,但它仍然有5个数字,我不能在最后一个字符串中使用0 1 O I。有什么好的建议吗?顺便说一句,只能使用大写字母。

2 个答案:

答案 0 :(得分:13)

归结为数学。如果您需要能够表示10 ^ 8个可能的数字,并且需要使用4个符号,则每个符号必须允许100个不同的值。 10^8^(1/4)您可以使用8位字节执行此操作,但您only upper case letters could be used.的要求表明您的选项相当有限。你必须确定100个可以使用的字母,或者你必须对你可以拥有的数字范围做出假设。

顺便说一句:如果您可以使用非ASCII大写字符,则没有问题。 ;)

有26个大写ASCII字符,30个大写字符,介于128和255之间,还有10个数字,因此您还必须使用34个符号。如果您可以使用Unicode,则有1898个大写和数字Unicode字符。

(char) 32(char) 255之间有163个非小写字符,如果您可以使用大部分字符,则可以执行此操作。


手工挑选的可能字符列表将是更好的选择,但这只是一个例子。

static final char[] ENCODE = new char[100];

static {
    int x = 0;
    for (char i = ' ' + 1; i < 256 && x < 100; i++)
        if (!Character.isLowerCase(i) && !Character.isWhitespace(i))
            ENCODE[x++] = i;
    assert x == ENCODE.length;
}

public static char[] encode(int n) {
    assert n >= 0 && n < 100000000;
    char[] ret = new char[4];
    for (int i = ret.length - 1; i >= 0; i--) {
        ret[i] = ENCODE[n % 100];
        n /= 100;
    }
    return ret;
}

public static int decode(char[] chars) {
    int n = 0;
    for (char ch : chars) {
        int x = Arrays.binarySearch(ENCODE, ch);
        assert x >= 0;
        n = n * 100 + x;
    }
    return n;
}

public static void main(String... args) {
    char[] chars = encode(12345678);
    System.out.println("Encoded: " + new String(chars));
    int n = decode(chars);
    System.out.println("Dencoded: " + n);
}

使用此字体不可打印的字符进行打印:(

Encoded: -CY
Dencoded: 12345678

答案 1 :(得分:1)

没有。八位数代表太多组合。每个十进制数字必须用单个符号表示,整个数字为长度为4的字符串。这意味着您需要使用100个符号。正如你所说,hex没有足够的字符,尽管它不仅仅是十进制。如果您不能使用小写字母,我假设也不允许使用标点符号。在这种情况下,你只是没有足够的符号。