Java 缩小数字的好方法
可能重复:Java 缩小数字的好方法,java,c++,c,algorithm,Java,C++,C,Algorithm,可能重复: 我有8个号码 有没有办法把它转换成长度为4的字符串 例如: 输入12345678 输出AB2D 转换应该能够准确地转换回 我试图将其转换为32十六进制,但它仍然有5个数字,并且无法在最后一个字符串中使用01OI。有什么好的建议吗?顺便说一句,只能使用大写字母。归结到数学。如果需要能够表示10^8个可能的数字,并且需要使用4个符号,则每个符号必须允许100个不同的值10^8^(1/4)您可以使用8位字节执行此操作,但您对的要求只能使用大写字母。表明您的选择相当有限。你必须确定你可以使
我有8个号码 有没有办法把它转换成长度为4的字符串 例如: 输入
12345678
输出AB2D
转换应该能够准确地转换回
我试图将其转换为32十六进制,但它仍然有5个数字,并且无法在最后一个字符串中使用
0
1
O
I
。有什么好的建议吗?顺便说一句,只能使用大写字母。归结到数学。如果需要能够表示10^8个可能的数字,并且需要使用4个符号,则每个符号必须允许100个不同的值10^8^(1/4)
您可以使用8位字节执行此操作,但您对的要求只能使用大写字母。
表明您的选择相当有限。你必须确定你可以使用的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);
}
不是。八位数字表示组合太多。每一个十进制数字都必须用一个符号来表示,整个数字是一个长度为4的字符串。这意味着您需要使用100个符号。正如你所说的,十六进制没有足够的字符,尽管它比十进制多。如果你不能使用小写字母,我假设标点符号也是不允许的。在这种情况下,您将没有足够的符号。如果您可以获得数字出现计数的统计信息,您可以使用哈夫曼算法对其进行编码。第1位表示出现次数最多,第1位表示出现次数最多,第1位表示出现次数最多,第1位表示出现次数最多,第010位表示出现次数最多。因此,您有(26-2)+(10-2)=32个字符。因此,最多可以表示32^4个不同的值,即1048576,小于12345678。上面说你做不到。如果我错了,请纠正我,但是AB2D并不是只使用大写字母……哈夫曼编码将以最大长度为代价减少平均长度。在这种情况下,它是限制的最大长度。@PeterLawrey:我假设每个8位数字都需要表示。
Encoded: -CY
Dencoded: 12345678