我有两个唯一的数字,10000-999999(固定的6个字符长度[0-9](,第二个1000000-9999999(固定7个字符长度[0-9](。我如何对这些数字进行编码/解码(解码后它们需要保持分离(,只使用大写字母[A-Z]和 [0-9]示例: 输入->编号1:242404,编号2:1002000 编码->AX3B O3XZ 解码->22424041002000 这类问题有算法吗?
这只是从一组值到另一组值的简单映射。程序始终相同:
- 列出所有可能的输入和输出值
- 查找输入的索引
- 返回该索引处输出列表的值
请注意,通常不需要制作实际列表(即将所有值加载到某个数据结构中(。您通常可以按需计算任何索引的值。这个案例也没什么不同。
想象一下所有可能的输入对的列表:
0 100'000, 1'000'000
1 100'000, 1'000'001
2 100'000, 1'000'002
...
K 100'000, 9'999'999
K+1 100'001, 1'000'000
K+2 100'001, 1'000'001
...
N-1 999'999, 9'999'998
N 999'999, 9'999'999
对于任何给定的对(a,b(,你可以在这个列表中计算它的索引i,如下所示:
// Make a and b zero-based
a -= 100'000
b -= 1'000'000
i = a*1'000'000 + b
将i转换为36进制(A-Z和0-9给出36个符号(,根据需要在左边加零1,并在第四位后面插入空格。
encoded = addSpace(zeroPad(base36(i)))
返回输入对:
将8个字符的36进制字符串转换为10进制(记住,这是列表的索引(,然后从索引中导出a和b。
i = base10(removeSpace(encoded))
a = i/1'000'000 + 100'000 // integer divison (i.e. ignore remainder)
b = i%1'000'000 + 1'000'000
以下是Go中的一个实现:https://play.golang.org/p/KQu9Hcoz5UH
1如果你不喜欢零填充的想法,你也可以在这一点上偏移i。目标值集足够大,你只需要所有36个基数中的32%左右的8位数或更少。