python题解:7-1 回文素数【函数】

一、题目

二、代码

def isPrime(num):
    for i in range(3, int(num ** 0.5) + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if len(str(prime)) == 4:
            prime += 9000
        if len(str(prime)) == 6:
            prime += 900000
        if isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
            if prime == 2:
                prime += 1
                continue
        if count == num:
            break
        if len(str(prime)) > 5:
            prime += 10
            continue
        prime += 2


if __name__ == '__main__':
    selfPrime(eval(input()))

三、代码改进过程

1.初始版本

在最开始的时候,我的代码是这样的

def isPrime(num):
    for i in range(2, int(num / 2) + 1):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
        if count == num:
            break
        prime += 1


selfPrime(eval(input()))

我先来解说一下这个代码

# 这个是一个判断是否为质数的函数
def isPrime(num):
    # 循环传进来的数字从2开始,然后把这个数除2减少循环次数,这是我最初的想法
    for i in range(2, int(num / 2) + 1):
        # 如果在循环中被除尽了就说明他不是质数,反之就是质数
        if num % i == 0:
            return False
    return True

# 判断是否是回文的函数
def palindrome(num):
    # 直接返回,相等就是true,不相等就是false
    return str(num) == str(num)[::-1]

# 这个就是主函数,判断是否为回文质数
def selfPrime(num):
    # count是用来控制次数
    count = 0
    # prime就是自己需要判断的数字
    prime = 2
    while True:
        # 只要符合是质数,回文也相等的数
        if isPrime(prime) and palindrome(prime):
            # count+1,并输出这个数
            count += 1
            print(prime, end=" ")
        # 当count数和输入的数字相等时就代表可以结束循环了
        if count == num:
            break
        # 需要让prime一次次增加,判断这个数是不是回文质数
        prime += 1

# 最后这个就是运行了
selfPrime(eval(input()))

只不过在test5的地方超时了

这就说明我的代码还不够效率

2.改进版本

第一次改进

import math


def isPrime(num):
    k = int(math.sqrt(num))
    for i in range(3, k + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue
        elif isPrime(prime) and palindrome(prime):
            count += 1
            print(prime,end=" ")
        if count == num:
            break
        prime += 1


selfPrime(eval(input()))

第一次改进在于判断质数的改进和判断回文质数的改进

import math


def isPrime(num):
    # 将传入的数开根号并转为int类型
    k = int(math.sqrt(num))
    # 从3开始循环,循环到k+1并且步长为2
    for i in range(3, k + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        # 如果能被2或者5除尽并且不是2或者5则prime+=1并且continue跳过本次循环使其不用判断是否为质数,提高效率
        if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue
        elif isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
        if count == num:
            break
        prime += 1


selfPrime(eval(input()))

  成功的过了test5,只不过之后我还是不满意

第二次改进

def isPrime(num):
    for i in range(3, int(num ** 0.5) + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue
        elif isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
            if prime == 2:
                prime += 1
                continue
        if count == num:
            break
        prime += 2


selfPrime(eval(input()))

第二次改进是将判断质数的函数进行精简,对判断回文质数的地方进行改进

def isPrime(num):
    # 去掉了math,直接使用int(num ** 0.5)来替换,以此来精简代码
    for i in range(3, int(num ** 0.5) + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue
        # 改成了elif
        elif isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
            # 如果prime是2就让prime+=1,其实只执行了一次
            if prime == 2:
                prime += 1
                continue
        if count == num:
            break
        # 最大的改进在这里,因为质数不可能是偶数,在prime=2那里使prime+=1后变成了3,后面每次都是prime+=2,以此来提高效率
        prime += 2


selfPrime(eval(input()))

 

 没想到只快了一点点,让我有些费解,但在后面也发现了问题所在

第三次改进

def isPrime(num):
    for i in range(3, int(num ** 0.5) + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if len(str(prime)) == 4:
            prime += 9000
        if len(str(prime)) == 6:
            prime += 900000
        if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue
        elif isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
            if prime == 2:
                prime += 1
                continue
        if count == num:
            break
        prime += 2


selfPrime(eval(input()))

在多次改进后,我发现没有4位数和6位数的回文质数,所以这次改进了判断回文质数

# 只要刚满1000变成4位数就直接+9000变成10000
if len(str(prime)) == 4:
    prime += 9000
# 同理直接+90w变成100w
if len(str(prime)) == 6:
    prime += 900000

 

 速度也大大增加了,但后面我又再次改进

第四次改进

def isPrime(num):
    for i in range(3, int(num ** 0.5) + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if len(str(prime)) == 4:
            prime += 9000
        if len(str(prime)) == 6:
            prime += 900000
        if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue
        elif isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
            if prime == 2:
                prime += 1
                continue
        if count == num:
            break
        if len(str(prime)) > 5:
            prime += 4
            continue
        prime += 2


selfPrime(eval(input()))
# 仅仅改进了这里,只要位数大于5,实际上就是7以上,则每次都prime+=4,不再是+=2
if len(str(prime)) > 5:
    prime += 4
    continue

 

 3.最终版本

def isPrime(num):
    for i in range(3, int(num ** 0.5) + 1, 2):
        if num % i == 0:
            return False
    return True


def palindrome(num):
    return str(num) == str(num)[::-1]


def selfPrime(num):
    count = 0
    prime = 2
    while True:
        if len(str(prime)) == 4:
            prime += 9000
        if len(str(prime)) == 6:
            prime += 900000
        if isPrime(prime) and palindrome(prime):
            count += 1
            print(prime, end=" ")
            if prime == 2:
                prime += 1
                continue
        if count == num:
            break
        if len(str(prime)) > 5:
            prime += 10
            continue
        prime += 2


if __name__ == '__main__':
    selfPrime(eval(input()))

在最后,发现百万级的每个回文质数都相差10倍数,所以就直接改成prime+=10

if len(str(prime)) > 5:
    # 改了这里
    prime += 10
    continue

 

 速度又变快了不少同时还发现了下面这个代码有些多余

 if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
            prime += 1
            continue

 可能当时第二次改进就是这里导致速度只快了一点点

四、结语

其实在最后发现那个prime+=10只能过200w以前的回文素数,因为300w之后的是已3为结尾,再后面以1为结尾的则是1亿多的数字了,这也是我这个代码的问题所在,但过个现在这个pta还是没问题的

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值