求素数问题
求素数问题(很典型的问题) 以下是求解素数的三种方法,大家可以按照算法写出程序代码。 【1】求10000以内的所有素数。 素数是除了1和它本身之外再不能被其他数整除的自然数。由于找不到一个通项公式来表示所有的素数,所以对于数学家来说,素数一直是一个未解之谜。像著名的哥德巴赫猜想、孪生素数猜想,几百年来不知吸引了世界上多少优秀的数学家。尽管他们苦心钻研,呕心沥血,但至今仍然未见分晓。 自从有了计算机之后,人们借助于计算机的威力,已经找到了2216091以内的所有素数。 求素数的方法有很多种,最简单的方法是根据素数的定义来求。对于一个自然数N,用大于1小于N的各个自然数都去除一下N,如果都除不尽,则N为素数,否则N为合数。 但是,如果用素数定义的方法来编制计算机程序,它的效率一定是非常低的,其中有许多地方都值得改进。 第一,对于一个自然数N,只要能被一个非1非自身的数整除,它就肯定不是素数,所以不 必再用其他的数去除。 第二,对于N来说,只需用小于N的素数去除就可以了。例如,如果N能被15整除,实际 上就能被3和5整除,如果N不能被3和5整除,那么N也决不会被15整除。 第三,对于N来说,不必用从2到N一1的所有素数去除,只需用小于等于√N(根号N)的所有素数去除就可以了。这一点可以用反证法来证明: 如果N是合数,则一定存在大于1小于N的整数d1和d2,使得N=d1×d2。 如果d1和d2均大于√N,则有:N=d1×d2>√N×√N=N。 而这是不可能的,所以,d1和d2中必有一个小于或等于√N。 基于上述分析,设计算法如下: (1)用2,3,5,7逐个试除N的方法求出100以内的所有素数。 (2)用100以内的所有素数逐个试除的方法求出10000以内的素数。 首先,将2,3,5,7分别存放在a[1]、a[2]、a[3]、a[4]中,以后每求出一个素数,只要不大于100,就依次存放在A数组中的一个单元中。当我们求100—10000之间的素数时,可依次用a[1]-a[2]的素数去试除N,这个范围内的素数可以不保存,直接打印。 【2】用筛法求素数。 在2的上面画一个圆圈,然后划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数;现在既未画圈又没有被划去的第一个数是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于N的各数都画了圈或划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 N的素数。 这很像一面筛子,把满足条件的数留下来,把不满足条件的数筛掉。由于这种方法是厄拉多塞首先发明的,所以,后人就把这种方法称作厄拉多塞筛法。 【3】用6N±1法求素数。 在程序上,我们可以用一个二重循环实现这一点,外循环i按3的倍数递增,内循环j为0-1的循环,则2(i+j)-1恰好就是形如6N±1的自然数。 |
评论