2013-03-25 3 views
0

자바에서 숙제를 주어 프라임 번호 등을 찾는 수업을 만들었습니다 (코드를 더 잘 보시면 알 수 있습니다).Prime Tester for speed

내 코드 :

class Primes { 

    public static boolean IsPrime(long num) { 
     if (num%2==0){ 
      return false; 
     } 

     for (int i=3; i*i<=num;i+=2) { 
      if (num%i==0) { 
       return false;  
      } 
     } 
     return true; 
    } // End boolen IsPrime 

    public static int[] primes(int min, int max){ 
     int counter=0; 
     int arcount=0; 

     for (int i=min;i<max;i++){ 
      if (IsPrime(i)){ 
       counter++; 
      } 
     } 

     int [] arr= new int[counter]; 
     for (int i=min;i<max;i++){ 
      if (IsPrime(i)){ 
       arr[arcount]=i; 
       arcount++; 
      }    
     } 
     return arr; 
    } // End Primes 

    public static String tostring (int [] arr){ 
     String ans=""; 
     for (int i=0; i<arr.length;i++){ 
      ans= ans+arr[i]+ " "; 
     } 
     return ans; 
    } 

    public static int closestPrime(long num){ 
     long e = 0 , d = 0 , f = num; 
     for (int i = 2; i <= num + 1 ; i++){ 
      if ((num + 1) % i == 0){ 
       if ((num + 1) % i == 0 && (num + 1) == i){ 
        d = num + 1; 
        break; 
       } 
       num++; 
       i = 1; 
      } 
     } 
     num = f; 
     for (int i = 2; i < num; i++){ 
      if ((num - 1) % i == 0){ 
       if ((num - 1) % i == 0 && (num - 1) == i){ 
        e = num - 1; 
        break; 
       } 
       num--; 
       i = 1; 
      } 
     } 
     num = f; 
     if (d - num < num - e) System.out.println("Closest Prime: "+d); 
     else System.out.println("Closest Prime: "+e); 

     return (int) num; 
    } // End closestPrime 

}//end class 

내 코드의 목표는 빠른 (정정)이 될 것입니다. 나는 이것을 달성하는 데 어려움을 겪고있다. 제안?

** 새로운 코드 : 나는 조금 더 나은 만들려고 않았다

class Primes { 

    public static boolean IsPrime(int num) { 

     if (num==1){ 
      return false; 
     } 
     for (int i=2; i<Math.sqrt(num);i++) { 
      if (num%i==0) { 
       return false; 
      } 
     } 
     return true; 
    } 
      // End boolen IsPrime 

    public static int[] primes(int min, int max){ 
     int size=0; 
     int [] arrtemp= new int[max-min]; 

     for (int i=min;i<max;i++){ 
      if (IsPrime(i)){ 
       arrtemp[size]=i; 
       size++; 
      } 
     } 

     int [] arr= new int[size]; 
     for (int i=0;i<size;i++){ 
       arr[i]=arrtemp[i]; 

      } 
     return arr; 

    } 

    public static String tostring (int [] arr){ 
     String ans=""; 
     for (int i=0; i<arr.length;i++){ 
      ans= ans+arr[i]+ " "; 
     } 
     return ans; 
    } 

    public static int closestPrime(int num) { 
     int count=1;  
     for (int i=num;;i++){ 

      int plus=num+count, minus=num-count; 
      if (IsPrime(minus)){ 

       return minus; 

      } 

      if (IsPrime(plus)) { 
       return plus; 

      } 
      count=count+1; 
     } 
    } // End closestPrime 

}//end class 

. 너는 무엇을 생각 하느냐, 더 향상시킬 수 있는가? (속도 테스트는 여전히 높습니다 ...)

+1

빠른 시스템 찾기? ;-) – assylias

+1

'primes'에서 각 숫자를 두 번 테스트합니다. 배열 대신 ArrayList를 사용하고 2에 가까운 시간으로 나눌 수 있습니다. – assylias

+0

안녕하세요, 아이디어의 주요 알고리즘 찾기 최적화 목록을 확인하십시오. http : //stackoverflow.com/questions/15467813/why-does-this-code-take-8-minutes-to-finish/15467938#15467938 – Patashu

답변

1

당신 :

  • 현재의 수는
  • 이 당신의 출력을 넣어 배열을 만들기 프라임 어떤지를 확인하기 위해 두
  • 검사로 나누어 있는지 확인
  • 확인합니다. 범위에있는 모든 숫자를 배열에 넣기 전에 소수성을 다시 나타냅니다.

문제는 마지막 단계입니다. 각 숫자가 소수인지 다시 확인하여 가장 비싼 작업을 복제합니다.

동적 데이터 구조를 사용하여 찾을 수있는 것처럼 소수를 추가 할 수 있습니다. 그렇게하면 한 번만 확인하면됩니다.

또는 입력 범위의 크기 인 부울 배열을 만들 수 있습니다. 그런 다음 소수를 찾을 때 해당 배열 값을 true로 설정하십시오.

UPDATE :

이 당신이 할 수있는 개선의 숫자는 여전히 있지만, 일부는 구현하기 위해 다른 사람보다 더 많은 작업이 필요합니다. 시험의 특성을보고 필요에 맞는 것을 확인하십시오.

낮은 교수형 과일 : 배의 값을 통해 반복 반대로 당신이 primes에서 찾을으로

  • 는 소수를 수집하는 ArrayList를 사용합니다.
  • closestPrime에서 각 값은 num입니다.이 중 절반은 균등하므로 소수가 아닙니다. 소수성에 대해서만 홀수를 검사하도록 코드를 조정할 수 있습니다. 난이도

구현하기 :

을 확인, 당신은 병목에있는 정확한 위치를 알아내는 시간을 할애해야 당신의 코드. 종종 성능 문제는 우리가 완벽하다고 생각했던 코드로 인해 발생합니다. 개발 환경에서 사용할 수있는 코드 프로파일 링 옵션을 고려해보십시오.

+0

Tnx, 나는 새로운 코드로 당신의 요지를 가지고 있다고 생각하지만 속도 테스트를 위해 여전히 느린 ... 그리고 나는 그것을 향상시킬 수 없다. 어떤 제안? – Alaev

+0

@ Alaev- 업데이트 : – dckrooney

0

isPrime()에 대한 호출이 많이 있습니다. 각 호출은 매우 비쌉니다. 첫 번째 단계는 주어진 횟수만큼 결과가 바뀌지 않으므로 횟수를 최소화하는 것입니다. 한 번만 호출하면됩니다. 빠른 속도로 그들에게 모든 시간을 다시 계산하지 않고

ArrayList<Integer> memoList = new ArrayList<Integer>(); 
for(int i = 0; i < max; i++) { 
    if(isPrime(i)) { 
    memoList.add(i); 
    } 
} 

지금 memoList가 max까지 당신이 필요로하는 모든 소수를 보유하고, 당신은 그들에 루프를 할 수 있습니다 당신은 그들이 계산하고 나면 값을 저장하여 memoization하여이 작업을 수행 할 수 있습니다 .

둘째, isPrime() 방법을 개선 할 수 있습니다. 당신의 솔루션은 3에서 sqrt (n)까지 모든 홀수로 반복됩니다.

public static boolean IsPrime(long num) { 
    for(int p : memoList) { 
     if(num % p == 0) { 
      return false; 
     } 
    } 
    return true; 
} 

이러한 변화는 극적으로 당신의 코드를 실행하는 방법을 신속하게 개선해야하지만, 소수를 계산하는 더 효율적인 방법으로 많은 연구되고있다. Prime Numbers에 Wikipedia 페이지는 실험 할 수있는 더 전술 (특히 주요한 sieves)에 아주 좋은 정보가있다.

숙제이므로이 페이지를 제출할 때 반드시이 페이지를 인용해야합니다.이 코드를 사용하고 확장 할 수는 있지만이 질문과 사용하는 다른 자료는 표절이라고 인용하지 마십시오.

0

답변에 몇 가지 문제점이 있습니다. 첫째, 2는 소수입니다. IsPrime의 첫 번째 조건부로이 문제가 해결됩니다. 둘째, 귀하의 소수 방법에서, 당신은 최소에서 최대까지 모든 숫자를 순환하고 있습니다. IsPrime에서와 마찬가지로 모든 음수와 모든 짝수를 안전하게 무시할 수 있습니다. 이 두 가지 방법을 결합하고 모든 여분의 사이클을 절약하는 것이 더 합리적입니다. 당신의 primes 기능에