답변:
여기에는 두 가지 일반적인 접근 방식이 있다고 생각합니다. 본질적으로 가장 긴 반복 문자열을 "브 루트 포스"로 찾거나 숫자 이론의 문제로 해결할 수 있습니다.
이 문제를 겪은 지 오랜 시간이 지났지 만 Project Euler의 특수 사례 (1 / n)는 26 번 문제이므로 해당 특정 이름에 대한 효율적인 솔루션을 검색하여 자세한 정보를 찾을 수 있습니다. 한 번의 검색으로 우리는 Eli Bendersky 웹 사이트를 방문 하여 솔루션 을 설명합니다 . Mathworld의 Decimal Expansions 페이지 의 이론은 다음과 같습니다 .
비정규 분수
m/n
는 주기적이며 기간과lambda(n)
독립적이며m
최대n-1
자릿수입니다. 경우n
그 기간, 10 상대적으로 소수lambda(n)
의m/n
의 약수phi(n)
대부분에서이phi(n)
숫자,phi
totient 기능입니다. 10lambda(n)
의 곱셈n
차수인 mod (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를 구분할 수 있습니다)
십진 확장이 유한 한 경우이 구현은 (철 론적으로) 영원히 반복되지만 무한 인 경우 종료됩니다! 그러나 2 또는 5가 아닌 n/d
모든 소인수가로 d
도 존재 하는 경우 유한 소수점 표시 만하 기 때문에이 경우를 확인할 수 있습니다 n
.
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
등
긴 분할? : /
결과를 문자열로 바꾸고이 알고리즘 을 적용 하십시오. 문자열이 일반 유형으로 충분하지 않은 경우 BigDecimal을 사용하십시오.