与素数有关的编程问题--C++٩۹(๑•̀ω•́ ๑)۶

  • 素数也即质数,质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
  1. 判断一个数是否为素数


    题目描述:输入一个正整数n,判断其是否为素数,若为素数,则输出“n为素数”;若不为素数,则输出“n不为素数”。

  2. 输出给定数n以内的所有素数


    题目描述:输入一个正整数n,把n以内所有的素数,以从小到大的顺序(相邻的数之间用空格隔开)输出。

 

第1题

思路分析:

要判断一个数是否为素数只需看其是否有除1和它本身外的因数,而找一个数的因数可以从1开始将n以内的所有数对n取余数(可利用for循环实现),若余数等于0,则该数为其的一个因数。

方法一:这里有一个性质,就是质数的因数个数等于2,而除1外的非质数的因数个数必大于2(或者说非质数的因数个数不为2)。通过数的因数个数可判断其是否为素数。而因数个数(我们用变量m来储存,并将之初始化为0)可通过每次上述条件成立时(即余数为0时)使变量m自加1得到。

这样我们就可以写代码如下:

4777fecd77ed4a2b9db9445075d73dba.jpg

 运行结果如下:

c2eb29dea94e4528ae1614295b964738.jpg

7347f3fd4db14bbc9775467ee78e4e40.jpg 

方法二:我们还可以这样做,就是我们让在2~(n-1)(即除去1和它本身)范围内的每个数分别对该数取余数(利用循环实现),然后每取一次,表示次数的变量m(初始化为0)加1,在其中一个数满足余数为0时立即退出循环,这样我们就会发现只有在该数为素数时,循环结束后变量m的值才会等于(n-1)。

用代码实现如下:

61efc5e561ba44d2a75bf99592115502.jpg

运行结果同上。

方法三:对于素数,我们知道,在2~(n-1)范围内,只要出现一个数使其对n取余数等于0,则该数不为素数。该论述可与这句话进行类比,即:n个数相乘,只要其中一个数为0,则该n个数的乘积为0。

故我们可以利用上述性质写代码如下:

1e69e8c57fe2417781c74e593a945071.jpg

运行结果同上。

对上述方法进行优化(即将遍历范围进行缩小):

首先我们应该知道如果数n的一个因数确定了,那么与其相对应的另一个因数也随之确定。

①将范围由1~n变为1~n/2:

对于这一做法,我们可以这样想,在1~n这个范围内,该数的最小因数为1,而它对应的因数为n(即它本身),那么2是第二小因数(如果n能被2整除的话),它对应的因数为n/2,如此一来在n/2~(n-1)范围内的数就都不是n的因数(那么这些数可以不用循环遍历)(因为没有介于1~2之间的因数了;而当n>2时,(n-1)>n/2恒成立,因为在大于2的整数中,数(n-1)不可能是数n的一个因数,即在第二大因数n/2和n之间还有非因数的整数,因此在两者之间还有数)。

②将范围由1~n变为1~sqrt(n):

可将sqrt(n)看做n的两个相等因数a和b,则数n若在b~n范围内有因数,则在1~a这一范围内必有因数与之对应,而在a~b这一范围内无其他数(也就是没有别的因数了),因此可将范围缩小到上述范围。

这里要注意了ƪ(˘⌣˘)ʃ:

使用sqrt()函数要引入头文件“#include<cmath>”。

还有在C++中,17/2的结果为8,sqrt(17)的结果为4。

将范围进行替换,而其他代码不变即实现了代码的优化(也可以认为是新方法哦(˃ ⌑ ˂ഃ ))。

第二题

思路分析:

利用两层循环,第一层遍历1~n内所有的数,第二层循环用来判断该遍历的数是否为素数(回到了第一题),是则将其输出。

代码略●)o(●

好啦,以上就是我对于这两道题的见解啦,希望能帮到在做这两道题的你啦(ง •̀_•́)ง(嘿嘿,本人也是个编程小白,也正在不断地学习和刷题哦)。本人能力有限,如果写的有什么不对的地方,还希望大佬指正(๑´∀`๑))!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值