素数判断方法的改进迭代

15 篇文章 3 订阅
11 篇文章 0 订阅

素数判断方法

V1:常规的判断素数方法:

代码

类似这样的

#include<bits/stdc++.h>
using namespace std;
int main(){
    int x;
    int is_prime = 1;  // 一开始假定输入的数是素数,原因如下
    cin >> x;

    if(x <= 1)  // 在一开始要对<=1和2做判断
        is_prime = 0;  // 因为任何数都可以整除1,所以for循环要从2开始
    else if(x == 2)  // 从2开始的话又没办法对2进行判断了,因为第一个要整除的数就是自己本身
        is_prime = 1;
    else{
        for(int i = 2; i < x; i++){  // 因为只要i能被x整除一次x就不是素数了
            if(x % i == 0)
                is_prime = 0;
        }
        
    }

    if(is_prime == 0)
        printf("x is not a prime number");
    else
        printf("x is a prime number");

    system("pause");
    return 0;
}
问题

在for循环中不对素数的因子取值范围做判断, 导致增加很多无用的循环次数

V2:改进后的判断素数方法

改进思想

给出一个数x, 使得两个数相乘等于该数x
称这两个数为x的因子factor
那么factor的最大取值几位sqrt(x)
即 factor * factor == x

改进之处

所以这时可以将循环的范围更改为x>=2 && x<=sqrt(x)

附加注意

但与此同时要在前面的判断中加上对3的判断
因为sqrt(3)的值是小于2的
如果不对3进行判断, 那么3是素数与否将无法被判断到

代码
#include<bits/stdc++.h>
using namespace std;
int main(){
    int x;
    int is_prime = 1; 
    cin >> x;

    if(x <= 1)  
        is_prime = 0;  
    else if(x == 2 || x == 3) 
        is_prime = 1;
    else{
        for(int i = 2; i <= sqrt(x); i++){ 
            if(x % i == 0)
                is_prime = 0;
        }
        
    }

    if(is_prime == 0)
        printf("x is not a prime number");
    else
        printf("x is a prime number");

    system("pause");
    return 0;
}
测试点

这时测试点就是if中判断值和判断值两边的数
在进入if最右边的数的考虑的时候, 就要去找for循环的上界, 以及上界中的特例

V3:在V2的基础上再改进一点

突然想到的问题

突然想到了如果输入的数据不规范的判断问题
可以想想但是没有必要用到这
如果输入是浮点数, 因为素数都是整数的性质
肯定要对输入的浮点数进行提示然后使其重新输入或退出程序

解决方法

那么如何判断输入的数是一个整数呢?
->使用强制类型转换的方法
->将一个所要判断的数使用强制类型转化为整数
->然后使用原数减去该整数, 若结果为0, 则可判断是为整数
->若结果不为零, 则为浮点数

改进方法
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin >> n;
	int is_prime = 1;
	int limit = sqrt(n) + 1;  // 此处加1或者不加1均可正确判断素数

	if(n <= 1)
		is_prime = 0;
	else if(n == 2)
		is_prime = 1;
	else if(n % 2 == 0)  // 这里不仅包含了对3的判断,还包含了对后面的奇数的判断
		is_prime = 0;
	else  // 如果是大于2的奇数,先视为是素数,之后再进行一个判断
		is_prime = 1;

	for(int i = 3; i <= limit; i += 2){  // 这里让i每次加2,即使得x每次都对奇数进行取余操作
		if(n % i == 0)  // 大于2的所有偶数均可被2整除,所以只需要判断大于2的奇数是否还有除自身和1以外的其他因子
			is_prime = 0;  // 大于2的奇数自然不可能被偶数整除,所以只需判断还能不能被大于2的其他的奇数整除
	}  
	
	system("pause");
	return 0;
}

这个方法不仅对要判断是否是素数的x本身进行了分析
同时对素数的分布规律也有分析和思考

利用素数的大于2之后的奇偶分布特征, 对输入数进行判别
相比于前一种改进又减少了近一半的循环次数

总结

三种方法的时间复杂度从O(n) -> O( log(n) ) -> O( log(n) / 2 )
效率是在一步步的提高的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Every DAV inci

小辣鸡一枚,不求打赏啦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值