算法——质数处理
来源:互联网 发布:算法的乐趣 pdf 编辑:程序博客网 时间:2024/06/05 17:35
质数的相关处理
1. 判断一个数是否是素数
只能被1和本身整除的自然数就是素数
如何判断一个数是否是素数
比较合适的方式就是不断的除余
#include"stdio.h"#include"math.h"int main( int argc, char* argv[]){ int i,k,m; while( scanf("%d",&i) && i != 0 ) { k=sqrt(i); //判别i是否为素数,只需使2~根号i之间的每一个整数去除 for(m=2;m<=k;m++) { if(i%m==0) break; } if(m>k) printf("%d是素数 ",i); else printf("%d不是素数",i); } return 0;}
运行结果:
2. 求一个范围数是否是素数
比较常规的是将上面的逻辑封装成一个函数,然后循环遍历判断每一个数
另外一种思路去处理有限范围内的素数查找
假如求1到4096之间的所有素数:
#include "stdafx.h"#include "stdio.h"#define SIZE 4096class CPrimeNum{public: CPrimeNum( int n ) { m_Attr[0] = 1; // 1不是质数 for( int i = 1; i < n; i++ ) { m_Attr[i] = 0; } int j = 0; for( ; i < SIZE; i++ ) { j++; if( j == n ) { m_Attr[i] = 1; j = 0; } else { m_Attr[i] = 0; } } } void MaskWith( CPrimeNum m ) { for( int i = 0; i < SIZE; i++ ) { m_Attr[i] = m_Attr[i] | m.m_Attr[i]; } } int m_Attr[SIZE];};CPrimeNum glbPrimeNum(2);int GetNextPrimeNum( int Current ){ for( int i = Current; i < SIZE; i++ ) { if( glbPrimeNum.m_Attr[i] == 0 ) return i+1; } return 0;}int main(){ int Current = 2; int Count = 1; while( Current ) { printf( "%d ", Current ); if( Count == 15 ) { printf("\n"); Count = 0; } Current = GetNextPrimeNum( Current ); Count++; glbPrimeNum.MaskWith(Current); } return 0;}
运行结果:
当然是不会有错误的啦,而且还比较高效,但是限于如果用的是数组成员变量,本身可能就无法获取太大范围的,所以可以考虑改良成 new 操作符去进行申请内存。
3. 求范围内的质数的优化型
#include "stdio.h"#include <string.h>class CPrimeNum{public: CPrimeNum( int MaxRange ) { m_nMaxRange = MaxRange; m_pAttr = new char[MaxRange]; } ~CPrimeNum() { if( m_pAttr ) delete []m_pAttr; }private: void MaskWithPrimeNum( int m ) { int j = 0; for( int i = m; i < m_nMaxRange; i++ ) { j++; if( j == m ) { m_pAttr[i] = 1; j = 0; } } } void InitAttr() { memset( m_pAttr, 0, sizeof(char)*m_nMaxRange ); int j = 0; for( int i = 2; i < m_nMaxRange; i++ ) { j++; if( j == 2 ) { m_pAttr[i] = 1; j = 0; } } } int GetNextPrimeNum( int m ) { for( int i = m; i < m_nMaxRange; i++ ) { if( m_pAttr[i] == 0 ) return i + 1; } return 0; }public: void PrintAll() { InitAttr(); int Current = 2; int Count = 1; while( Current ) { printf( "%d ", Current ); if( Count == 15 ) { printf("\n"); Count = 0; } Current = GetNextPrimeNum( Current ); Count++; MaskWithPrimeNum(Current); } } char* m_pAttr; int m_nMaxRange;};void main(){ CPrimeNum PrimeNum(10000); PrimeNum.PrintAll();}
运行结果:
刚好和上述可以相互应证
我们修改main函数来测试下效率
设置断点,并运行:
花了84.657秒计算出了100万以内的所有质数,速度上貌似有点慢,总体还是前面的遍历赋值的时候的消耗比较多。
正在寻求更加有效的方式….
4.用遍历判断方式去查找所有质数
#include "stdafx.h"#include"stdio.h"#include"math.h"#include <windows.h>bool bPrime( int g ){ int i,k,m; k = sqrt(g); for(m=2;m<=k;m++) { if(i%m==0) break; } if(m>k) return true; else return false;}int main( int argc, char* argv[]){ long t1 = GetTickCount(); for( int i = 1; i < 1000000; i++ ) { bPrime(i); } long t2 = GetTickCount(); long t = t2 - t1; return 0;}
最后结果:
t = 32 毫秒 (哦,myGod, 肯定是我打开的方式不对)
0 0
- 算法——质数处理
- 【质数算法】——判断质数、求小于N的质数、求前N个质数
- 典型算法——质数判断
- 蓝桥杯练习系统算法训练——质数的乘积
- java小算法—判断一个数是否为质数
- 质数算法
- 质数算法
- 质数算法
- 孪生质数——孤独的质数
- 黑马程序员——求质数算法的优化:编程打印所有的3位质数,质数:只能被1和其本身整除
- JavaScript——生成质数
- JAVA-(6)——质数
- 6——质数因子
- 刷题——质数因子
- JS——质数判断
- 第二周作业1——判断一个正整数是否为质数的算法
- 第二周作业 2.1——判断一个正整数是否为质数的算法
- 找质数算法
- spring mvc入门教程(一)概念介绍
- 反射笔记
- HCDA
- 带你快速玩转canvas(8)非常用API的说明集
- Caffe error Cannot copy param 0 weights from layer, shape mismatch
- 算法——质数处理
- 永远要设定Deadline,完成比完美更重要
- Hadoop与Spark以及那些坑
- vs2012 error c4996 'fopen'
- perl 循环截取字符串
- scp后台运行
- SDWebImage加载图片URL第一次失败,后面图片URL存在不刷新的问题
- swift 2.2基本数据类型详解
- 防止网页被外部调用