Answers:
我相信这里有两种通用方法,您可以从本质上“蛮力”寻找最长的重复字符串,也可以将其作为数论问题解决。
自从我遇到这个问题已经很长时间了,但是特例(1 / n)是Euler项目上的问题26,因此您可以通过搜索该特定名称的有效解决方案来找到更多信息。一次搜索将我们带到Eli Bendersky的网站,他在那里解释了他的解决方案。这是Mathworld的“ 十进制展开”页面中的一些理论:
任何非规则分数
m/n
都是周期性的,并且具有lambda(n)
独立于的周期,该周期m
最多n-1
为数位。如果n
是相对素10,则周期lambda(n)
的m/n
是一个约数phi(n)
,并具有最高phi(n)
的数字,其中phi
是欧拉函数。事实证明,这lambda(n)
是10(模)的乘法阶n
(Glaisher 1878,Lehmer 1941)。有理数的十进制扩展的重复部分中的位数也可以直接从其分母的乘法顺序中找到。
目前,我的数论有点生锈,所以我能做的最好的就是将您指向那个方向。
让我们来n < d
,您正在尝试找出的重复部分n/d
。设p
重复部分的位数:然后n/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...)
。方括号中的部分是一个几何级数,等于1/(10^p - 1)
。
这样n / d = R / (10^p - 1)
。重新排列以获得R = n * (10^p - 1) / d
。为了找到R,循环p
从1到无穷大,并停止尽快d
整除n * (10^p - 1)
。
这是Python中的实现:
def f(n, d):
x = n * 9
z = x
k = 1
while z % d:
z = z * 10 + x
k += 1
return k, z / d
(例如,k
跟踪重复序列的长度,因此您可以区分1/9和1/99)
请注意,如果十进制扩展名是有限的,则此实现(具有讽刺意味的是)永远循环,但如果无限扩展,则终止!不过,您可以检查这种情况,因为n/d
如果的所有素数d
都不是2或5,那么它也只有有限的十进制表示形式n
。
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
等
长除法?:/
将结果转换为字符串,然后对其应用此算法。如果您的字符串对于普通类型不够长,请使用BigDecimal。