考虑到
0 -- is the first
1 -- is the second
2 -- is the third
.....
9 -- is the 10th
11 -- is the 11th
什么是找到第 n 个回文数的有效算法?
考虑到
0 -- is the first
1 -- is the second
2 -- is the third
.....
9 -- is the 10th
11 -- is the 11th
什么是找到第 n 个回文数的有效算法?
我假设 0110 不是回文,因为它是 110。
我可以花很多话来描述,但这张表应该足够了:
#Digits #Pal. Notes
0 1 "0" only
1 9 x with x = 1..9
2 9 xx with x = 1..9
3 90 xyx with xy = 10..99 (in other words: x = 1..9, y = 0..9)
4 90 xyyx with xy = 10..99
5 900 xyzyx with xyz = 100..999
6 900 and so on...
偶数位数的(非零)回文数从 开始p(11) = 11, p(110) = 1001, p(1100) = 100'001,...
。它们是通过获取索引n - 10^L
、 whereL=floor(log10(n))
并附加此数字的反转来构造的:p(1101) = 101|101, p(1102) = 102|201, ..., p(1999) = 999|999, etc
。对于索引,必须考虑这种情况n >= 1.1*10^L but n < 2*10^L
。
当 时n >= 2*10^L
,我们得到具有奇数位数的回文串,它以 开头p(2) = 1, p(20) = 101, p(200) = 10001 etc.
,并且可以以相同的方式构造,再次使用n - 10^L with L=floor(log10(n))
,并附加该数字的反转,现在没有最后一位数字: p(21) = 11|1, p(22) = 12|1, ..., p(99) = 89|8, ...
。
当 时,从 L 中减去 1 以在奇数位数的情况下n < 1.1*10^L
处于正确的设置中。n >= 2*10^L
这产生了简单的算法:
p(n) = { L = logint(n,10);
P = 10^(L - [1 < n < 1.1*10^L]); /* avoid exponent -1 for n=1 */
n -= P;
RETURN( n * 10^L + reverse( n \ 10^[n >= P] ))
}
如果 ... 为真,则 [...] 为 1,否则为 0,\ 是整数除法。(表达式n \ 10^[...]
等价于:if ... then n\10 else n
。)
(我在指数中添加了条件 n > 1 以避免 P = 10^(-1) for n=0。如果您使用整数类型,则不需要这个。另一个选择是放置 max(..., 0) 作为 P 中的指数,或者if n=1 then return(0)
在开始时使用。另外请注意,在分配 P 之后您不需要 L,因此您可以对两者使用相同的变量。)