2016-05-06 23 views
0

このプログラムを実行すると、再帰(ループは許されません)を使用して回文素数を出力するように作成されました。ただし、これは200〜800などのかなり大きな入力でのみ発生します。OSXはPythonを予期せずに終了し、Pythonを終了します

何か理由はありますか?

私のコードは次のとおりです。

import sys 
sys.setrecursionlimit(30000) 
    def isprime(start,end,divisor): 
     if start == end: 
      return -1 
     else: 
      if divisor == start: 
       a = str(start) 
       b = str(start)[::-1] 
       if a == b: 
        print(b)    
       return isprime(start+1,end,2) 
      elif start%divisor == 0: 
       return isprime(start+1,end,2) 
      else: 
       return isprime(start,end,divisor+1)  

    def main(): 
     n = eval(input('Enter the starting point N:''\n')) 
     m = eval(input('Enter the ending point M:''\n')) 
     divisor = 2 
     print('The palindromic primes are:') 
     primenumbers = isprime(n,m,divisor) 

    main() 
+0

「Terminal.app」内で直接実行して、何が起こるかを確認してください。 – enedil

+0

'sys.setrecursionlimit(30000)' - それをしないでください。 Pythonの再帰制限は、Cレベルのスタックオーバーフローからあなたを守るためのもので、Pythonのスタックオーバーフローよりもはるかに扱いにくいです。 – user2357112

+0

それは課題であり、それを置くように私たちに言った – Chora

答えて

1

問題は、あなたの周り20K再帰でスタックフレームを使い果たしている - あなたは400の中の数字をテストする時間については、この制限をヒット。私。番号ごとにスタックフレームが多すぎます。これを改善する1つの方法は、それぞれのフレームに費用がかかるため、より少ない除数をテストし、必要以上にテストしています。私。あなたが2 to sqrt(N)をテストする必要があるときには2からNをテストしています

もう1つの問題は、明示的なリターンとプログラムにもかかわらず、有用な結果を返さないということです最後に価値を期待している。これらの問題の両方が下に取り組まれています。

import sys 
import math 

sys.setrecursionlimit(30000) 

def ispalindrome(x): 
    y = str(x) 
    return y == y[::-1] 

def ispalindromeprime(start, end, divisor=2): 

    palindrome_primes = [] 

    if start == end: 
     pass 

    elif divisor > int(math.sqrt(start)): 
     if ispalindrome(start): 
      print(start) # optional 
      palindrome_primes.append(start)  
     palindrome_primes.extend(ispalindromeprime(start+1, end)) 

    elif start % divisor == 0: 
     palindrome_primes.extend(ispalindromeprime(start+1, end)) 

    else: 
     palindrome_primes.extend(ispalindromeprime(start, end, divisor+1)) 

    return palindrome_primes 

def main(): 
    n = int(input('Enter the starting point N: ')) 
    m = int(input('Enter the ending point M: ')) 

    print('The palindromic primes are:') 
    numbers = ispalindromeprime(n, m) 
    print(numbers) 

if __name__ == "__main__": 
    main() 

これは2500年の周りに約400から自分の限界をバンプと回文のリストは、素数を返します。私たちは、切断することにより、私たちのテストをさらにプッシュすることができます

Enter the starting point N: 2 
Enter the ending point M: 2500 
The palindromic primes are: 
2 
3 
5 
7 
11 
101 
131 
151 
181 
191 
313 
353 
373 
383 
727 
757 
787 
797 
919 
929 
[2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383, 727, 757, 787, 797, 919, 929] 

私たちがテストした数の半分と、私たちがテストした数々とである。私。奇数と除数との特別なケースとだけ仕事として「2」を扱う:それはこれ以上の結果を見つけたものの

def ispalindromeprime(start, end, divisor=3): 

    palindrome_primes = [] 

    if start >= end: 
     pass 

    elif start % 2 == 0: 
     if start == 2: 
      print(start) # optional 
      palindrome_primes.append(start)  
     palindrome_primes.extend(ispalindromeprime(start+1, end)) 

    elif divisor > int(math.sqrt(start)): 
     if ispalindrome(start): 
      print(start) # optional 
      palindrome_primes.append(start)  
     palindrome_primes.extend(ispalindromeprime(start+2, end)) 

    elif start % divisor == 0: 
     palindrome_primes.extend(ispalindromeprime(start+2, end)) 

    else: 
     palindrome_primes.extend(ispalindromeprime(start, end, divisor+2)) 

    return palindrome_primes 

これは、4500の周りに、あなたの限界をバンプ。 (それはあなたのプログラムの速度を上げるんが)

UPDATE

私たちはより良い行うことができます - 右再帰スタック自体の限界までの限界を押してください。代わりに、素数とテストを生成するので、彼らは回文であれば、彼らは素数(他のコードは同じまま)であれば、我々はより簡単に回文とテストを生成できます。

def isprime(number, divisor=3): 

    if number <= 2 or number % 2 == 0: 
     return number == 2 

    if divisor > int(math.sqrt(number)): 
     return True 

    if number % divisor == 0: 
     return False 

    return isprime(number, divisor+2) 

def ispalindromeprime(n, m): 

    palindromeprimes = [] 

    if n == m: 
     return palindromeprimes 

    if ispalindrome(n) and isprime(n): 
     print(n) # optional 
     palindromeprimes.append(n) 

    palindromeprimes.extend(ispalindromeprime(n+1, m)) 

    return palindromeprimes 

今、私たちもして、私たちの以前の制限を超えてプッシュすることができます再帰的なソリューション:我々は唯一の(2以外)奇数をテストする必要がありますので

Enter the starting point N: 1 
Enter the ending point M: 20000 
The palindromic primes are: 
2 
... 
929 
10301 
10501 
10601 
11311 
11411 
12421 
12721 
12821 
13331 
13831 
13931 
14341 
14741 
15451 
15551 
16061 
16361 
16561 
16661 
17471 
17971 
18181 
18481 
19391 
19891 
19991 
[2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383, 727, 757, 787, 797, 919, 929, 10301, 10501, 10601, 11311, 11411, 12421, 12721, 12821, 13331, 13831, 13931, 14341, 14741, 15451, 15551, 16061, 16361, 16561, 16661, 17471, 17971, 18181, 18481, 19391, 19891, 19991] 

は、我々は再びこれを倍増することができます

def ispalindromeprime(n, m): 

    palindromeprimes = [] 

    if n > m: 
     return palindromeprimes 

    if ispalindrome(n) and isprime(n): 
     print(n) # optional 
     palindromeprimes.append(n) 

    if n == 1 or n % 2 == 0: 
     n -= 1 

    palindromeprimes.extend(ispalindromeprime(n+2, m)) 

    return palindromeprimes 

はさらに大きな結果を取得:

Enter the starting point N: 1 
Enter the ending point M: 50000 
The palindromic primes are: 
2 
... 
19991 
30103 
30203 
30403 
30703 
30803 
31013 
31513 
32323 
32423 
33533 
34543 
34843 
35053 
35153 
35353 
35753 
36263 
36563 
37273 
37573 
38083 
38183 
38783 
39293 
[2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383, 727, 757, 787, 797, 919, 929, 10301, 10501, 10601, 11311, 11411, 12421, 12721, 12821, 13331, 13831, 13931, 14341, 14741, 15451, 15551, 16061, 16361, 16561, 16661, 17471, 17971, 18181, 18481, 19391, 19891, 19991, 30103, 30203, 30403, 30703, 30803, 31013, 31513, 32323, 32423, 33533, 34543, 34843, 35053, 35153, 35353, 35753, 36263, 36563, 37273, 37573, 38083, 38183, 38783, 39293] 
+0

ありがとう – Chora

関連する問題