我正在开发一个在数字基数之间转换的程序。例如八进制是 8,十进制是 10。字母A
toZ
可以被认为是基数 26。
我想将“A”之类的数字转换为 0,将 Z 转换为 25,将“AA”转换为 27,将“BA”转换为 53。
在我开始编码之前,我会在纸上做,所以我了解这个过程。首先,我试图将 533 转换为基数 26。
什么算法最适合这样做?
您需要为每个字母分配一个“数字”,例如:
A = 0 N = 13
B = 1 O = 14
C = 2 P = 15
D = 3 Q = 16
E = 4 R = 17
F = 5 S = 18
G = 6 T = 19
H = 7 U = 20
I = 8 V = 21
J = 9 W = 22
K = 10 X = 23
L = 11 Y = 24
M = 12 Z = 25
然后,你的{20,13}
变成UN
.
转换回来是UN -> {20,13} -> (20 * 26 + 13) -> 52
。
再举一个例子,让我们试试随机从空中抽取的数字 10163。
将其除以 26,直到得到小于 26 的数字(即两倍),得到15,小数部分为 0.03402366。
将其乘以 26,得到0,小数部分为 0.88461516。
将它乘以26 得到23(实际上在我的计算器上是 22.99999416,但由于最初的除法只有两步,所以我们在这里停止 - 非常轻微的不准确是由于浮点数被四舍五入的事实)。
所以“数字”{15,0,23}
就是“数字” PAX
。哇,这么巧?
要转换PAX
回十进制,它的
P * 262 + A * 261 + X * 260
或者
(15 * 676) + (0 * 26) + 23
= 10140 + 0 + 23
= 10163
让我们退后一步,看看十进制。
像“147”这样的数字是什么意思?或者更确切地说,字符“1”、“4”和“7”这样排列时表示什么?
十进制有十位数字,然后,我们在第一个数字的左边添加另一个数字,随着数字的增加,依此类推。所以在 "9" = 9*1 之后,我们得到 "10" = 1*10 + 0*1。所以“147”是 1*10^2 + 4*10 + 7*1 = 147。类似地,我们可以倒退 - 147/10^2 = 1,它映射到字符 '1'。(147 % 10^2) / 10 = 4,映射到字符“4”。而 147 % 10 = 7,映射到字符“7”。
这适用于任何基数 N - 如果我们得到数字 0,它映射到我们集合中的第一个字符。数字 1 映射到第二个字符,以此类推,直到数字 N-1 映射到我们数字集中的最后一个字符。
您将 20 和 13 转换为以 26 为基数表示法表示 20 和 13 的符号。听起来您正在使用字母表中的字母,所以那将是 UN(其中 A 为 0,Z 为 25)。
你用什么语言写这个?如果您在 Perl 中执行此操作,您可以使用多年前我无聊时编写的 CPAN 模块 Math::Fleximal。如果您使用的是具有无限精度整数的语言,那么生活会变得容易得多。您所要做的就是获取字符,将它们转换为整数数组,然后进行计算以将其转换为数字。