【问题标题】:How would i make my python code below more efficient and simple for this recursive function?对于这个递归函数,我如何使下面的 python 代码更高效和简单?
【发布时间】:2021-06-07 05:09:26
【问题描述】:

我需要使用递归函数来查找作为输入提供的两个整数 N、M 之间的所有回文素数。 (包括起点和终点)。

  • 回文数是从正面和背面读取相同的数字。 例如:212、44、9009、4567654。
  • 要计算一个数字是否是回文,请将您的答案合并到 问题 1。
  • 素数是大于 1 且只能被 1 和自身整除的数。

例如:3、11、313。

回文素数的一些例子是:11、191、313。

你可以假设总是 N>1,并且 N≤M。

您不得在程序中使用任何形式的循环!

我在下面包含了我的代码,想知道是否可以对其进行检查,如果可以,您能否解释一下我如何使它更简单或更高效。(您是否也可以包括 cmets 来解释不同的代码行? )

import sys
sys.setrecursionlimit (30000)

def palindromeprimes(M,N,lst):
    def pr_num(point,end = 1):
        if end == point:
            return True
        else:
            if point % end == 0 and end != 1:
                return False
            else:
                return pr_num(point, end + 1)   
            
    def reverse(sub_phrase):
        if sub_phrase == "":
            return sub_phrase
        else:
            return reverse(sub_phrase[1:]) + sub_phrase[0]    
        
    if M >=N:
        if pr_num(M,1):
            if M==int(reverse(str(M))):
                lst.append(M)
        palindromeprimes (M-1,N,lst)
lst = []
N = eval(input("Enter the starting point N: \n"))
M = eval(input("Enter the ending point M: \n"))
print ("The palindromic primes are:")  

palindromeprimes(M,N,lst)

array1 = sorted(lst)
def printlst(array1,pos=0):
    if pos<len(array1):
        print(array1[pos])
        return printlst(array1,pos+1)
printlst(array1,0)

样本输入/输出:

Enter the starting point N:
200
Enter the ending point M:
800
The palindromic primes are:
313
353
373
383
727
757
787
797

【问题讨论】:

  • 分析代码的一个好方法是找出你的时间在运行时间和内存方面的复杂性,也许你可以从那里开始看看你的算法是否足够好,然后再重构代码让它看起来更干净更简单。较短的代码通常更好,但并非总是如此。
  • 一个写着“你不能在你的程序中使用任何形式的循环”的作业显然不关心效率。
  • 另外这类问题更适合 [code-review]。
  • 任何原因,为什么您在收集输入时使用 eval 函数?
  • 永远不要在用户输入中使用eval,除非您愿意让任何用户有机会在您的计算机上安装恶意软件!

标签: python recursion primes palindrome


【解决方案1】:

这个怎么样。这更短。而且更快。

import sys
sys.setrecursionlimit(4000)
def check_prime(num_list,number):
    if num_list==[]:
        print(number)
    else:
        num=num_list[0]
        
        
        if number % num == 0:
            pass
        else:
            num_list.pop(0)
            check_prime(num_list,number)
def check_palindrome(nums):
    nums1=nums[::-1]
    if nums1==nums:
        new_list=list(range(2,int(nums)))
        check_prime(new_list,int(nums))
def check_done(lists):
    if lists!=[]:
        check_palindrome(str(lists[0]))
        lists.pop(0)
        check_done(lists)


start_int=int(input("Enter starting number: "))
ending_int=int(input("Enter ending number: "))
list1=list(range(start_int,ending_int+1))
check_done(list1)

样品测试

Enter starting number: 200
Enter ending number: 800
313
353
373
383
727
757
787
797

【讨论】:

  • 如何将此代码用于更大的数字,例如 10000 到 20000
  • 是的,我知道,只是增加递归限制。由于没有循环,这对于大量数据来说有点慢
【解决方案2】:

真的需要递归吗?

如果没有,这段代码会更快更高效。

def isPalindrome(s):
    if (s == s[::-1]) and isPrime(int(s)):
        return True
    return False


def isPrime(number):
    for i in range(2, number):
        if (number % i) == 0:
            return False
    return True


N = eval(input("Enter the starting point N: \n"))
M = eval(input("Enter the ending point M: \n"))
print("The palindromic primes are:")

for N in range(N, M):
    if isPalindrome(str(N)):
        print(N)

【讨论】:

  • “你不能在你的程序中使用任何形式的循环”由 OP 指定
【解决方案3】:

我相信最好的解决方案是让部分独立于整体而易于理解和测试。这个解决方案在大数上应该更快:

def palindromeprimes(start, end):
    def is_prime(number, divisor=3):
        if number < 2:
            return False

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

        if divisor * divisor > number:
            return True

        if number % divisor == 0:
            return False

        return is_prime(number, divisor + 2)

    def is_palindrome(string):
        if len(string) <= 1:
            return True

        if string[0] != string[-1]:
            return False

        return is_palindrome(string[1:-1])

    numbers = []

    if start <= end:
        if is_palindrome(str(start)) and is_prime(start):
            numbers.append(start)

        numbers.extend(palindromeprimes(start + 1, end))

    return numbers

print(palindromeprimes(200, 800))

一些功能包括不对偶数进行质数测试(速度和递归更少);在主要测试之前进行回文测试(先进行更容易/更快的测试);没有额外的参数,也没有预先计算列表;没有隐式循环(例如range() 运算符)。

输出

% python3 test.py
[313, 353, 373, 383, 727, 757, 787, 797]
%

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-04
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-06
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多