zoukankan      html  css  js  c++  java
  • python学习——练习题(12)

    """
    题目:判断101-200之间有多少个素数,并输出所有素数。
    质数(prime number)又称素数,有无限个。
    质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
    """
    
    import math
    
    
    def answer1():
        """
        根据素数定义,一个一个判断
        :return:
        """
        print("输出一", end=":")
        sumCount = 0
        findTimes = 0
        for i in range(101, 2000):
            for j in range(2, i):
                findTimes += 1
                if i % j == 0:
                    break
            else:
                print(i, end=",")
                sumCount += 1
        print("共%d个" % sumCount, end=",")
        print("共比较了%d次" % findTimes)
    
    
    answer1()
    
    
    def answer2():
        """
        上述判断方法,明显存在效率极低的问题。对于每个数n,其实并不需要从2判断到n-1,我们知道,一个数若可以进行因数分解,
        那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中并不需要遍历到n-1,遍历到sqrt(n)即可,
        因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数。
        :return:
        """
        print("输出二", end=":")
        sumCount = 0
        findTimes = 0
        for i in range(101, 2000):
            sqrtNum = int(math.sqrt(i))
            for j in range(2, sqrtNum + 1):
                findTimes += 1
                if i % j == 0:
                    break
            else:
                print(i, end=",")
                sumCount += 1
        print("共%d个" % sumCount, end=",")
        print("共比较了%d次" % findTimes)
    
    
    answer2()
    
    
    def answer3():
        """
            方法(2)应该是最常见的判断算法了,时间复杂度O(sqrt(n)),速度上比方法(1)的O(n)快得多。最近在网上偶然看到另一种更高效的方法,暂且称为方法(3)吧,
        由于找不到原始的出处,这里就不贴出链接了,如果有原创者看到,烦请联系我,必定补上版权引用。下面讲一下这种更快速的判断方法;
        首先看一个关于质数分布的规律:大于等于5的质数一定和6的倍数相邻。例如5和7,11和13,17和19等等;
        证明:令x≥1,将大于等于5的自然数表示如下:
        ······ 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ······
        可以看到,不在6的倍数两侧,即6x两侧的数为6x+2,6x+3,6x+4,由于2(3x+1),3(2x+1),2(3x+2),所以它们一定不是素数,再除去6x本身,
        显然,素数要出现只可能出现在6x的相邻两侧。这里有个题外话,关于孪生素数,有兴趣的道友可以再另行了解一下,由于与我们主题无关,暂且跳过。
        这里要注意的一点是,在6的倍数相邻两侧并不是一定就是质数。
        根据以上规律,判断质数可以6个为单元快进,即将方法(2)循环中i++步长加大为6,加快判断速度,代码如下:
    
        高手无处不在啊
    
        由上可得,只要从96开始,每6个计算一次
        :return:
        """
        print("输出三", end=":")
        sumCount = 0
        findTimes = 0
        for i in range(102, 2000, 6):
            for num in (i - 1, i + 1):
                sqrtNum = int(math.sqrt(num))
                for j in range(2, sqrtNum + 1):
                    findTimes += 1
                    if num % j == 0:
                        break
                else:
                    print(num, end=",")
                    sumCount += 1
        print("共%d个" % sumCount, end=",")
        print("共比较了%d次" % findTimes)
    
    
    answer3()
    
    
    def answer4():
        """
        上面的方法,高手还可以改进
        因为上述可得,6x-1和6x+1坑定不会被6x,6x+2,6x+3,6x+4整除,弱它是素数,那么它也是被6x-1或6x+1整除
        所以上面方法,里面的判断也可以跨6来判断
        :return:
        """
        print("输出四", end=":")
        sumCount = 0
        findTimes = 0
        for i in range(102, 2000, 6):
            for num in (i - 1, i + 1):
                sqrtNum = int(math.sqrt(num))
                for j in range(5, sqrtNum + 1, 6):
                    findTimes += 1
                    if num % j == 0 or num % (j + 2) == 0:
                        break
                else:
                    print(num, end=",")
                    sumCount += 1
        print("共%d个" % sumCount, end=",")
        print("共比较了%d次" % findTimes)
    
    
    answer4()
    
    
    def answer5():
        """
        排除偶数,数组统计
        :return:
        """
        print("输出五", end=":")
        findTimes = 0
        numList = []
        for i in range(101, 2000, 2):
            numList.append(str(i))
            sqrtNum = int(math.sqrt(i))
            for j in range(2, sqrtNum + 1):
                findTimes += 1
                if i % j == 0:
                    numList.pop()
                    break
        print(",".join(numList), end=",")
        print("共%d个" % len(numList), end=",")
        print("共比较了%d次" % findTimes)
    
    
    answer5()
    
    
    class answer6:
        """
        练习迭代器
        """
    
        def __init__(self):
            """
            构造函数
            """
            self.sumCount = 0
            self.findTimes = 0
            self.startNum = 102
            self.endNum = 2000
            print("输出六", end=":")
    
        def __iter__(self):
            """
            迭代器
            :return:
            """
            return self
    
        def __next__(self):
            """
            迭代器next
            :return:
            """
            if self.startNum > self.endNum:
                raise StopIteration
            for num in (self.startNum - 1, self.startNum + 1):
                sqrtNum = int(math.sqrt(num))
                for i in range(5, sqrtNum + 1, 6):
                    self.findTimes += 1
                    if num % i == 0 or num % (i + 2) == 0:
                        break
                else:
                    print(num, end=",")
                    self.sumCount += 1
            self.startNum += 6
    
    
    answer = answer6()
    for i in answer:
        pass
    print("共%d个" % answer.sumCount, end=",")
    print("共比较了%d次" % answer.findTimes)
    
    
    def answer7():
        """
        练习yield生成器,注意和answer6区域
        """
        print("输出七", end=":")
        startNum = 102
        sumCount = 0
        findTimes = 0
        while startNum < 2000:
            for num in (startNum - 1, startNum + 1):
                sqrtNum = int(math.sqrt(num))
                for i in range(5, sqrtNum + 1, 6):
                    findTimes += 1
                    if num % i == 0 or num % (i + 2) == 0:
                        break
                else:
                    sumCount += 1
                    print(num, end=",")
                    yield num
            startNum += 6
        print("共%d个" % sumCount, end=",")
        print("共比较了%d次" % findTimes)
    
    
    for i in answer7():
        pass
    
    
    def answer8():
        """
        练习数组生成器表达式
        参考:http://blog.csdn.net/u014745194/article/details/70176117
        :return:
        """
        print("输出八", end=":")
        numList = list(filter(lambda x: x not in set([i for i in range(101, 200) for j in range(2, i - 1) if not i % j]),
                              range(101, 200)))
        print(numList, end=",")
        print("共%d个" % len(numList))
    
    
    answer8()
    

      

  • 相关阅读:
    跑Linux内存占用率的shell脚本
    Mysql数据导入导出功能(设置及使用)
    Python刷CSDN阅读数(仅供娱乐)
    SSH、SCP命令及使用说明
    2020.6.7 时间记录
    3年经验,中级Java开发招聘信息
    中级Java程序员要求
    提升自身内部核心竞争力要素
    三级联动页面
    大公司和小公司程序员
  • 原文地址:https://www.cnblogs.com/longphui/p/8066297.html
Copyright © 2011-2022 走看看