문제

나는 매우 많은 수의 가장 큰 주요 요인을 찾기 위해 프로그램을 작성하려고 노력하고 있으며 다양한 성공을 가진 몇 가지 방법을 시도했습니다. 내가 지금까지 발견 한 모든 사람들은 믿을 수 없을 정도로 느 렸습니다. 나는 생각이 있었고 이것이 유효한 접근법인지 궁금합니다.

long number = input;

while(notPrime(number))
{
    number = number / getLowestDivisiblePrimeNumber();
}

return number;

이 접근법은 입력이 필요하며 다음을 수행합니다.

200-> 100-> 50-> 25-> 5 (반품)

90-> 45-> 15-> 5 (반환)

CurrentNum 자체가 프라임이 될 때까지 (CurrentNum의 Squareroot보다 나열 가능한 소수가 적은 소수가 없음) CurrentNum을 가장 작은 분할 수 (대부분 2 또는 3)로 반복적으로 나누고 원래 입력의 가장 큰 주요 요인이라고 가정합니다.

이것은 항상 작동합니까? 그렇지 않다면 누군가 나에게 반례를 줄 수 있습니까?

-

편집 : 매우 큰 것은 약 2^40 또는 10^11을 의미합니다.

도움이 되었습니까?

해결책

이것은 항상 작동하기 때문에 작동합니다 독특한 주요 요인화 정리.

다른 팁

이 방법은 작동하지만 느립니다. "당신의 숫자는 얼마나 큽니까?" 사용할 방법을 결정합니다.

확실히 작동 할 것입니다 (참조 마크 바이어스의 대답), 그러나 "매우 큰"입력의 경우 너무 오래 걸릴 수 있습니다. 당신은 당신의 전화에 주목해야합니다 getLowestDivisiblePrimeNumber() 다른 루프를 숨기므로 O (n^2)에서 실행되며 "매우 큰"이라는 의미에 따라 작업해야 할 수도 있습니다. bignums 느리게 될 것입니다.

알고리즘이 마지막으로 발견 된 것보다 작은 요인을 확인할 필요가 없다는 점에 주목하여 약간의 속도를 높일 수 있습니다.

당신은 그것을 찾으려고 노력하고 있습니다 주요 요인 숫자의. 당신이 제안하는 것은 효과가 있지만 여전히 많은 숫자는 느리게 진행될 것입니다 .... 대부분의 현대 보안은 어려운 문제가되기 때문에 감사해야합니다.

방금 한 빠른 검색에서 숫자를 고려하는 가장 빠른 알려진 방법은 타원 곡선 방법을 사용하는 것입니다.

이 데모에서 번호를 던질 수 있습니다. http://www.alpertron.com.ar/ecm.htm .

그것이 당신을 설득한다면, 당신은 코드를 훔치는 것을 시도 할 수 있습니다 (재미는없고, 그것에 대한 링크를 제공합니다!) 다른 곳에서 이론을 읽을 수 있습니다. 여기에 대한 위키 백과 기사가 있습니다. http://en.wikipedia.org/wiki/lenstra_elliptic_curve_factorization 그러나 나는 그것을 이해하기에는 너무 어리 석다. 고맙게도, 그것은 내 것이 아니라 당신의 문제입니다! :)

Project Euler의 문제는 일반적으로 문제를 수행하는 명백한 무차별 적 방법이 있다는 것입니다. 질문이 더 어려워지면 영리한 솔루션을 구현해야합니다.

이 문제를 해결할 수있는 한 가지 방법은 항상 숫자의 가장 작은 (양수 정수) 계수를 찾는 루프를 사용하는 것입니다. 숫자의 가장 작은 요인이 그 숫자라면, 당신은 가장 큰 주요 요인을 찾았습니다!

자세한 알고리즘 설명 :

세 가지 변수를 유지 하여이 작업을 수행 할 수 있습니다.

요소를 고려하려는 숫자 (a) 현재 디바이저 저장소 (b) 가장 큰 디바이저 스토어 (c)

처음에 (a) 관심있는 숫자가되도록하자 -이 경우 600851475143입니다. 그런 다음 (b) 2로하자. 분리 가능한 경우 (a)를 (b)로 나누고 (b)를 2로 재설정하고 (a)를 (b)로 나눌 수 있는지 확인하십시오. 그렇지 않으면 (a)가 (b)로 나눌 수없는 경우, (b)만큼 +1로 (a)가 (b)에 의해 나눌 수 있는지 확인하십시오. (a)가 1이 될 때까지 루프를 실행하십시오. (3) 반품은 600851475143의 가장 큰 프라임 디바이저가됩니다.

다음 정수를 증가시키는 대신 다음 정수를 증가시키는 대신, 다음으로 필수 정수를 증가시킬 수 있으며, 가장 큰 디바이저 스토어를 유지하는 대신 유일한 디바이저가있는 경우 현재 번호를 반환 할 수 있습니다. 그 자체. 그러나 위에서 설명한 알고리즘은 몇 초 안에 실행됩니다.

파이썬에서의 구현은 다음과 같습니다.-

def lpf(x):
        lpf = 2;
        while (x > lpf):
                if (x%lpf==0):
                        x = x/lpf
                        lpf = 2
                else:
                        lpf+=1;
        print("Largest Prime Factor: %d" % (lpf));

def main():
        x = long(raw_input("Input long int:"))
        lpf(x);
        return 0;

if __name__ == '__main__':
    main()

예 : 위에서 설명한 방법을 사용하여 가장 큰 주요 요인 105를 찾아 봅시다.

(a) = 105를하자. (b) = 2 (우리는 항상 2로 시작), 아직 (c)에 대한 값이 없습니다.

(a)는 (b)로 나눌 수 있습니까? 아니요. 증분 (b) x +1 : (b) = 3입니다. (a) (b)에 의해 나눌 수 있습니까? 예. (105/3 = 35). 지금까지 발견 된 가장 큰 제수는 3입니다.

이제 (a) (b)로 나눌 수 있습니까? 아니요. 증분 (b) x +1 : (b) = 3. (a) (b)에 의해 나눌 수 있습니까? 아니요. 증분 (b) x +1 : (b) = 4. (a) (b)로 나눌 수 있습니까? 아니요. 증분 (b) x +1 : (b) = 5. (a) (b)로 나눌 수 있습니까? 예. (35/5 = 7). 우리가 이전에 찾은 가장 큰 제수는 (c)에 저장됩니다. (c)는 현재 3입니다. 5는 3보다 크기 때문에 (c) = 5를 업데이트합니다. 우리는 (a) = 7을 업데이트합니다. 우리는 (b) = 2를 재설정합니다.

그런 다음 (a)에 대한 프로세스를 반복하지만 (b) = (a)가 될 때까지 (b)가 계속 증가 할 것입니다. )> ((a)/2), 숫자의 절반보다 큰 정수 제수를 가질 수 없으므로 - 가장 작은 구분 (1 이외의 숫자)은 2입니다!)

그래서 그 시점에서 우리는 (a) = 7으로 돌아옵니다.

손으로 몇 가지를 시도해 보면 아이디어를 얻을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top