반복되는 십진수를 찾는 효율적인 방법은 무엇입니까


24

두 정수의 반복되는 십진 부분 abwhere 을 찾기 위해 Java에서 효율적인 알고리즘을 찾으려고합니다 a/b.

예. 5/7 = 0.714258 714258 ....

나는 현재 긴 분할 방법 만 알고 있습니다.


2
그래서 당신은 a = 5와 b = 7을 가지고 있고, 당신은 부동 소수점에서 a / b를 충분히 쉽게 계산할 수 있지만, 당신이 알고 싶은 것은 소수점 이하 6 자리 후에 반복한다는 것입니다.
Sparr

답변:


10

여기에는 두 가지 일반적인 접근 방식이 있다고 생각합니다. 본질적으로 가장 긴 반복 문자열을 "브 루트 포스"로 찾거나 숫자 이론의 문제로 해결할 수 있습니다.

이 문제를 겪은 지 오랜 시간이 지났지 만 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)숫자, phitotient 기능입니다. 10 lambda(n)곱셈n 차수인 mod (Glaisher 1878, Lehmer 1941) 이 밝혀졌습니다 . 유리수의 십진 확장의 반복 부분에있는 자릿수는 분모의 곱셈 순서에서 직접 찾을 수도 있습니다.

나의 수론은 현재 약간 녹슨 편이다. 그래서 내가 할 수있는 최선은 그 방향으로 당신을 가리킨다.


8

하자 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을 찾으려면 p1에서 무한대까지 반복 하고 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.


1
이 대답은 맞습니다. 이 방법은 다음과 같은 "규칙"을 기반으로합니다. 0.123123... = 123/999 0.714258714258... = 714258/999999 (=5/7)
COME FROM

4
이 1/6 또는 5/12 같은 경우 실패 : \
razpeitia

1
@razpeitia 나는 비슷한 것을 만들었지 만 모든 경우에서 작동합니다 (정수 나누기 포함). 체크 아웃 : codepad.org/hKboFPd2
Tigran Saluev

나는에 @ TigranSaluev의 유사한 자바 스크립트 구현을했습니다 github.com/Macil/cycle-division
Macil

2

긴 분할? : /

결과를 문자열로 바꾸고이 알고리즘 을 적용 하십시오. 문자열이 일반 유형으로 충분하지 않은 경우 BigDecimal을 사용하십시오.


4
"문자열로 바꾸려면"문자열의 반복 부분의 두 복사본을 계산하기 위해 임의의 정밀 계산과 매우 긴 문자열이 필요할 수 있습니다 (그리고 계산을 언제 중지해야하는지 어떻게 알 수 있습니까? .121212312121231212123 ... 문제가 될 것입니다)
Sparr

@Sparr 반복 길이는 항상 분모보다 작습니다.

@MichaelT 나는 그것을 몰랐다. 참이면 정밀도는 정확하게 "임의"가 아니지만 분모에 따라 임의로 높을 수 있습니다.
Sparr


나는 당신이 연결하는 알고리즘이 수정없이 작동한다고 생각하지 않습니다. 여기에는 겹치는 반복이 포함되어 있으며 연속 일치뿐만 아니라 문자열 전체를 검색합니다. 예를 들어 "banana"에서 가장 긴 반복 부분 문자열은 "ana"입니다.
Web_Designer 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.