当前位置: 首页 > 编程日记 > 正文

素数、最大公约数、最下公倍数、质因数分解

2013-08-18 11:20:43

素数、最大公约数、最下公倍数、质因数分解都是与素数相关的,解决了素数的问题,其他的都可以此为基础求解。

小结:

  1. 求1到n之间的素数的基本方法是通过遍历2到sqrt(n),判断每个数是否是素数来得到,但这种方法效率很低;比较高效的解法是通过筛选法求解,如下面代码中函数GetPrimeUnderNBySieve;
  2. 最大公约数可通过GCD递归定理求解,通俗的说法就是辗转相除法,《算法导论》中有详细的说明;
  3. 最下公倍数可通过最大公约数得到,公式为:LCM(a,b) = a*b / GCD(a,b);
  4. 质因数分解可通过质数表得到,如下面代码中函数GetPrimeFactorByPrimeTable所示;
  5. 另外,最后一种因数分解代码是最简练的,如函数Decomposition所示:
 1 void Decomposition(int nNum)
 2 {
 3     for(int i=2;i<nNum;)
 4     {
 5         if(nNum % i == 0)
 6         {
 7             nNum = nNum /i;
 8             cout<<i<<",";
 9         }
10         else
11         {
12             i++;
13         }
14     }
15     if(1<nNum)
16         cout<<nNum<<endl;
17 }

注意几点:

  • 可以用乘法代替开方,进行循环结束的判断
i * i <= num
  • 删选法时,筛子的下标变化可以通过相加或相乘来实现,如下:

相乘:

 1 for (primeIndex = 2;primeIndex * primeIndex < number;++primeIndex)
 2     {
 3         if (primeFlagArray[primeIndex])
 4         {
 5             for (sieveIndex = 2;sieveIndex * primeIndex <= number;++sieveIndex) //sieveIndex * primeIndex <= number
 6             {
 7                 primeFlagArray[sieveIndex * primeIndex] = false;
 8             }
 9         }
10     }

相加:

 1 for (primeIndex = 2;primeIndex * primeIndex < number;++primeIndex)
 2     {
 3         if (primeFlagArray[primeIndex])
 4         {
 5             for (sieveIndex = primeIndex + primeIndex;sieveIndex <= number;sieveIndex += primeIndex) //sieveIndex * primeIndex <= number
 6             {
 7                 primeFlagArray[sieveIndex] = false;
 8             }
 9         }
10     }

代码(包含测试,暂时没有发现错误,欢迎交流指正!):

  1 #include <iostream>
  2 #include <cassert>
  3 #include <cmath>
  4 using namespace std;
  5 
  6 
  7 //显示数组元素
  8 void DisplayArray(size_t *array,size_t len)
  9 {
 10     assert(array != NULL);
 11     for (size_t index = 0;index < len;++index)
 12     {
 13         cout<<array[index]<<"\t";
 14     }
 15     cout<<endl;
 16 }
 17 
 18 //判断一个数是否为质数
 19 bool IsPrime_basic(size_t num)
 20 {
 21     assert(num >= 2);
 22     for (size_t i = 2;i < num;++i)
 23     {
 24         if (num % i == 0)
 25         {
 26             return false;
 27         }
 28     }
 29     return true;
 30 }
 31 
 32 //判断一个数是否为质数
 33 bool IsPrime_improve(size_t num)
 34 {
 35     assert(num >= 2); 
 36     //for (size_t i = 2;i < sqrt(num);++i) // ambiguous call to overloaded function
 37     for (size_t i = 2;i < (int)sqrt((double)num);++i)
 38     {
 39         if (num % i == 0)
 40         {
 41             return false;
 42         }
 43     }
 44     return true;
 45 }
 46 
 47 //判断一个数是否为质数
 48 bool IsPrime(size_t num)
 49 {
 50     assert(num >= 2);
 51     for (size_t i = 2;i * i <= num;++i)  //i * i <= num而非i * i < num
 52     {
 53         if (num % i == 0)
 54         {
 55             return false;
 56         }
 57     }
 58     return true;
 59 }
 60 
 61 //用筛选法求素数
 62 size_t GetPrimeUnderNBySieve(size_t number,size_t *primeArray)
 63 {
 64     assert(primeArray != NULL);
 65 
 66     size_t primeIndex = 0;
 67     size_t sieveIndex = 0;
 68     size_t primeCounter = 0;
 69     bool *primeFlagArray = new bool[number + 1];//number + 1
 70     size_t index;
 71 
 72     for (index = 2;index <= number;++index)  //index从2开始,而非从0开始;index <= number,而非index < number
 73     { 
 74         primeFlagArray[index] = true;
 75     }
 76 
 77     //memset(primeFlagArray,1,sizeof(bool) * number);
 78 
 79     for (primeIndex = 2;primeIndex * primeIndex < number;++primeIndex)
 80     {
 81         if (primeFlagArray[primeIndex])
 82         {
 83             for (sieveIndex = 2;sieveIndex * primeIndex <= number;++sieveIndex) //sieveIndex * primeIndex <= number
 84             {
 85                 primeFlagArray[sieveIndex * primeIndex] = false;
 86             }
 87         }
 88     }
 89 
 90     for (index = 2;index <= number;++index)    //index <= number
 91     {
 92         if (primeFlagArray[index])
 93         {
 94             primeArray[primeCounter++] = index;
 95         }
 96     }
 97     delete [] primeFlagArray;
 98     return primeCounter;
 99 }
100 
101 //用筛选法求素数
102 size_t GetPrimeUnderNBySieve_2(size_t number,size_t *primeArray)
103 {
104     assert(primeArray != NULL);
105 
106     size_t primeIndex = 0;
107     size_t sieveIndex = 0;
108     size_t primeCounter = 0;
109     bool *primeFlagArray = new bool[number + 1];//number + 1
110     size_t index;
111 
112     for (index = 2;index <= number;++index)  //index从2开始,而非从0开始;index <= number,而非index < number
113     { 
114         primeFlagArray[index] = true;
115     }
116 
117     //memset(primeFlagArray,1,sizeof(bool) * number);
118 
119     for (primeIndex = 2;primeIndex * primeIndex < number;++primeIndex)
120     {
121         if (primeFlagArray[primeIndex])
122         {
123             for (sieveIndex = primeIndex + primeIndex;sieveIndex <= number;sieveIndex += primeIndex) //sieveIndex * primeIndex <= number
124             {
125                 primeFlagArray[sieveIndex] = false;
126             }
127         }
128     }
129 
130     for (index = 2;index <= number;++index)    //index <= number
131     {
132         if (primeFlagArray[index])
133         {
134             primeArray[primeCounter++] = index;
135         }
136     }
137     delete [] primeFlagArray;
138     return primeCounter;
139 }
140 
141 //用递归法求GCD
142 size_t GetGCDByRecursion(size_t a,size_t b)
143 {
144     if (b ==0)
145     {
146         return a;
147     }
148     
149     return GetGCDByRecursion(b,a % b);
150 }
151 
152 //用循环求GCD
153 size_t GetGCDByIteration(size_t a,size_t b)
154 {
155     size_t aTmp = 0;
156     while (b != 0)
157     {
158         aTmp = a;
159         a = b;
160         b = aTmp % b;
161     }
162 
163     return a;
164 }
165 
166 //用GCD求LCM,LCM(a,b) = a*b / GCD(a,b) 
167 size_t GetLCM(size_t a,size_t b)
168 {
169     return ( (a * b) / GetGCDByRecursion(a,b) );
170 }
171 
172 //求一个质数的下一个质数
173 size_t GetNextPrime(size_t currentPrime)
174 {
175     int curNum = currentPrime + 1;
176     while ( !IsPrime(curNum) )
177     {
178         ++curNum;
179     }
180     return curNum;
181 }
182 
183 //根据质数表求质因数分解
184 void GetPrimeFactorByPrimeTable(size_t num,size_t *primerFactor,size_t *pCnt)
185 {
186     *pCnt = 0;
187     if ( IsPrime(num))
188     {
189         primerFactor[(*pCnt)++] = num;
190         return;
191     }
192 
193     size_t *primeArray = new size_t[num];
194     size_t primeCounter = 0;
195     primeCounter = GetPrimeUnderNBySieve_2(num,primeArray);
196 
197     cout<<"the number of primes under "<<num<<" is :"<<primeCounter<<",they are :"<<endl;
198     DisplayArray(primeArray,primeCounter);
199 
200     assert(primeCounter <= num);
201     size_t index = 0;
202 
203     //for (index = 2;index * index < num;++index)
204     //while (index < primeCounter)
205     while (primeArray[index] <= num)
206     {
207         if (num % primeArray[index] == 0)
208         {
209             primerFactor[(*pCnt)++] = primeArray[index];
210             num = num / primeArray[index];
211             index = 0;
212 
213             //if ( IsPrime(num))
214             //{
215             //    primerFactor[(*pCnt)++] = num;
216             //    return;
217             //}
218         }
219         else
220         {
221             ++index;
222         }
223     }
224 
225     delete [] primeArray;
226 }
227 
228 //质数为自然数,所以此处的输入num为不小于最小质数2的自然数
229 //输入参数:num,待处理数字
230 //    primerFactor,存放num的质因数的数组的首地址
231 //    pCnt,存放数组长度的空间的地址
232 void GetPrimeFactor(size_t num,size_t *primerFactor,size_t *pCnt)
233 {
234     assert(num >= 2);
235     *pCnt = 0;
236     const size_t MinPrime = 2;
237     size_t currentPrime = 0;
238     while ( !IsPrime(num)  )
239     {
240         currentPrime = MinPrime;
241         while (num > currentPrime )  //num 不可能等于 currentPrime ,因为有外层while条件的保证
242         {
243             if (num % currentPrime == 0)  //从最小的质数开始,判断是否为num的因数,若不是判断下一个质数
244             {
245                 primerFactor[(*pCnt)++] = currentPrime;
246                 num = num / currentPrime;
247                 break;
248             }
249             else
250             {
251                 currentPrime = GetNextPrime(currentPrime);  //求当前质数的下一个质数
252             }
253         }
254     }
255     primerFactor[(*pCnt)++] = num;  //写入最后一个质因数
256 }
257 
258 //直接求质因数分解
259 void Decomposition(int nNum)
260 {
261     for(int i=2;i<nNum;)
262     {
263         if(nNum % i == 0)
264         {
265             nNum = nNum /i;
266             cout<<i<<",";
267         }
268         else
269         {
270             i++;
271         }
272     }
273     if(1<nNum)
274         cout<<nNum<<endl;
275 }
276 
277 //测试
278 void TestGetPrimeUnderN()
279 {
280     size_t number = 0;
281     size_t *primeArray = NULL;
282     size_t primeCounter = 0;
283     cout<<"TestGetPrimeUnderN..."<<endl;
284     cout<<"please enter a number(end with ctrl + z)"<<endl;
285     while (cin>>number)
286     {
287         primeArray = new size_t[number];
288         //primeCounter = GetPrimeUnderNBySieve(number,primeArray);
289         primeCounter = GetPrimeUnderNBySieve_2(number,primeArray);
290         cout<<"the number of primes under "<<number<<" is :"<<primeCounter<<",they are :"<<endl;
291         DisplayArray(primeArray,primeCounter);
292         cout<<"please enter a number(end with ctrl + z)"<<endl;
293         delete [] primeArray;
294     }
295 }
296 
297 void TestGetGCDAndLCM()
298 {
299     size_t a = 0;
300     size_t b = 0;
301 
302     
303     cout<<"TestGetGCD..."<<endl;
304     cout<<"please enter two numbers(end with ctrl + z)"<<endl;
305     while (cin>>a>>b)
306     {
307         cout<<"(GetGCDByRecursion)the GCD of "<<a<<" and "<<b<<" is : "<<GetGCDByRecursion(a,b)<<endl;
308         cout<<"(GetGCDByIteration)the GCD of "<<a<<" and "<<b<<" is : "<<GetGCDByIteration(a,b)<<endl;
309         cout<<"the LCM of "<<a<<" and "<<b<<" is : "<<GetLCM(a,b)<<endl;
310         cout<<"please enter two numbers(end with ctrl + z)"<<endl;
311     }
312 }
313 
314 //测试代码
315 void TestDriverGetPrimeFactor()
316 {
317     const size_t MaxNumberOfPrimeFactor = 100;
318     size_t primerFactor[MaxNumberOfPrimeFactor];
319     size_t Cnt = 0;
320     //size_t *pCnt = &Cnt;   //不能不定义Cnt,而直接用*pCnt
321     size_t num;
322 
323     cout<<"please enter a number(end with ctrl + z)"<<endl;
324     while (cin>>num)
325     {
326         //GetPrimeFactor(num,primerFactor,pCnt );
327         GetPrimeFactorByPrimeTable(num,primerFactor,&Cnt);
328         cout<<"the prime factor of number "<<num<<" is :"<<endl;
329         DisplayArray(primerFactor,Cnt);
330 
331         Decomposition(num);
332         cout<<"please enter a number(end with ctrl + z)"<<endl;
333     }
334 }
335 
336 //main
337 int main()
338 {
339     TestDriverGetPrimeFactor();
340     //TestGetPrimeUnderN();
341     //TestGetGCD();
342     return 0;
343 }

转载于:https://www.cnblogs.com/youngforever/p/3265790.html

相关文章:

Spring注解 开发

转载于:https://www.cnblogs.com/JBLi/p/10489541.html

读书:个人成长 -- 即兴演讲

与人交流时&#xff0c;有人发言语无伦次&#xff0c;舌头像打了结。 有人一开讲便滔滔不绝&#xff0c;却毫无重点。 也有人说话索然无味&#xff0c;没法让你投以关注。 如何在任何场合游刃有余地表达&#xff1f; 如何掌控此时此刻&#xff0c;用说话影响他人&#xff1f; …

php mysql环境搭配_centos6.7下搭配apache php mysql环境

安装过程安装apacheapache默认端口为80, 而nginx默认端口也是80, 所以安装apache前, 检查是否安装了nginx, 确保80端口没有被占用, 然后执行以下命令安装apacheyum install httpd httpd-devel启动apache服务/etc/init.d/httpd start或service httpd start停止apache服务/etc/in…

我们如此努力,也不过是个普通人

http://www.nowamagic.net/librarys/eight/posts/2500文 / 張君雅 南方日报曾刊登了一条新闻&#xff0c;大意是说有个女孩子以她的成绩考入北大清华没问题。但她从小参加各种社会活动&#xff0c;深受曾留学法国的母亲“生命的意义在于体验最多而不是最好”影响&#xff0c;决…

Citrix XenServer@cloudstack基本功能测试报告2

Cloudstack功能测试1、创建Zone、Pod、Clusters&#xff0c;添加hosts、Primary Storage、Secondary Storage步骤&#xff1a;1、 登录cloudstack控制板2、 选择基础架构&#xff0c;选择区域&#xff0c;点击查看全部&#xff0c;然后点击添加区域3、 选择基本区域类型4、 输入…

ABP中的Filter(下)

接着上面的一个部分来叙述&#xff0c;这一篇我们来重点看ABP中的AbpUowActionFilter、AbpExceptionFilter、AbpResultFilter这三个部分也是按照之前的思路来一个个介绍&#xff0c;当然这里面如果和前面的Interceptor有重复的部分&#xff0c;那么将会对两者进行一个对比并作出…

LRU算法 -- 链表 完整实现

LRU算法(Least Recently Used) 算是我们经常遇到的一种淘汰算法&#xff0c;其中内存管理模块进行内存页回收时有用到&#xff0c;针对不经常使用的内存页&#xff0c;LRU淘汰策略能够将该内存页回收给操作系统。 属于 我们操作系统设计中的 时间局部性原理&#xff0c;最长时…

python getostime_python中sys,os,time模块的使用(包括时间格式的各种转换)

sys模块sys.argv: 实现从程序外部向程序传递参数。位置参数argv[0]代表py文件本身&#xff0c;运行方法 python xx.py 参数1&#xff0c;参数2 。。self sys.argv[0]name sys.argv[1]age sys.argv[2]print self, name, agesys.getdefaultencoding(): 获取系统当前编码&#…

关于SpringMVC和Struts2的区别

1. 与struts2不同 1、 springmvc的入口是一个servlet即前端控制器&#xff0c;而struts2入口是一个filter过虑器。 2、 springmvc是基于方法开发&#xff0c;传递参数是通过方法形参&#xff0c;可以设计为单例或多例(建议单例)&#xff0c;struts2是基于类开发&#xff0c…

DC-RC加固修补型砂浆

DC-RC加固修补型砂浆www.hrbjg.net一、DC-RC加固修补型砂浆的产品特点&#xff1a;1、耐火、耐高温、耐腐蚀、耐老化性能优良。2、强度高&#xff0c;抹灰操作性好。3、与原混凝土结构的粘结性能良好。4、无收缩&#xff0c;基本不会产生裂缝。5、二氧化碳、氯化物等透过性差&a…

类,实例,属性习题

class Restaurant(): def __init__(self,restaurant_name,cuisine_type): self.restaurant_namerestaurant_name self.cuisine_typecuisine_type def describle_restaurant(self): print("打印的第一条消息") print("打印的第…

数据结构和算法 -- 学习导图

数据结构和算法 是作为程序员写出高效代码的基础&#xff0c;为了今后的两年在高效代码之路上持续精进&#xff0c;将按照此学习导图进行 算法和数据结构的刻意练习&#xff0c;同时也希望为同样有高效代码追求的伙伴们提供一条学习路径&#xff0c;共同进步。 以下为今后持续…

HDU 1248 寒冰王座(全然背包:入门题)

HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,仅仅有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前. 死亡骑士:"我要买…

java 彩票系统_JAVA版彩票随机生成系统

import java.io.*;import java.util.Random;class num{public static void main(String[]args){//声明一个随机数组int sjsh[]new int[7];int sum;try{InputStreamReader anew InputStreamReader(System.in);BufferedReader bnew BufferedReader(a);System.out.println ("…

Windows Server 2012 文件服务器群集

概述&#xff1a;之前已经测试了Windows Server 2012系统群集、Hyper-V群集&#xff0c;接下来将测试Windows Server 2012 文件服务器群集功能。实验环境&#xff1a;4台服务器都为Windows Server 2012 DataCenter操作系统在之前配置了群集的基础上&#xff0c;SRV2012服务器新…

023 判断出栈顺序是否正确

1.题目 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否为该栈的弹出顺序。 假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列&#xff0c;序列4、5、3、2、1是该压栈序列对应的一个弹出序列&#xff0c;但4、3…

栈 -- 顺序栈、链式栈的实现 及其应用(函数栈,表达式求值,括号匹配)

文章目录实现顺序栈实现链式栈实现应用函数栈 的应用表达式求值中 的应用括号匹配中 的应用我们使用浏览器的时候经常会用到前进、后退功能。依次访问完一串页面 a – b – c之后点击后退功能&#xff0c;则能够依次看到c – b – a的页面。但是这个过程中&#xff0c;如果后退…

OC中的NSArray和NSMutableArray、NSDictionary和NSMutableDictionary用法

一&#xff1a;NSArray 和NSMutableArray1: NSArray&#xff1a;不可变数组NSArray是OC中使用的数组&#xff0c;只能用来存放OC对象&#xff0c;不能存放非OC对象如基本数据类型它使不可变的&#xff0c;一旦初始化完毕&#xff0c;内容不能改变&#xff0c;也不能添加元素。而…

java中ContentArea_java中TextArea怎么加载指定路径的文本内容

展开全部这设计到IO操作&#xff0c;很62616964757a686964616fe58685e5aeb931333332643334久以前练手写的加载文本到文本域的界面。具体代码第一步&#xff1a;得到一个File对象&#xff0c;需要参数文本路径File file new File("C:\\test.txt");第二步&#xff1a;…

文本分类技术基础

分类体系 分类&#xff1a;给定一个对象&#xff0c;从一个事先定义好的分类体系中挑出一个或多个最适合该对象的类别。 文本分类(TC, Text Categorization)&#xff1a;在给定的分类体系下&#xff0c;根据文本内容自动的确定文本关联的类别。从数学角度看&#xff0c;文本分类…

C# 返回值为 listT

public List<T> test<T>(List<T> EntityList) where T : class{return EntityList;} 转载于:https://www.cnblogs.com/enych/p/10497312.html

ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析

文章目录内存查看内存控制内存控制源码分析通过gperftools接口获取osd进程实际内存 动态设置cache大小动态调整cache比例trim释放内存本文通过对ceph-osd内存查看跟踪的5种手段以及osd内存控制的方式进行源码层面的说明&#xff0c;并未通过修改相关源码进行控制&#xff08;水…

c语言函数库学习~sscanf~格式化输入

---恢复内容开始--- 今天算是被打击到了吧&#xff0c;由郑轻的acm老师来我学院指导安排了个现场的小比赛&#xff0c;&#xff0c;俺们居然有还是输给一个大一的新手&#xff0c;&#xff0c;哎&#xff0c;情何以堪&#xff0c;&#xff0c;所以还是要重视下基础编程能力的培…

java mobile phone games_j2me100-src Java

文件名大小更新时间codesc.net\[J2SE]应用编程150例\chap01\实例1\BorderLayoutDemo.class8192003-07-07codesc.net\[J2SE]应用编程150例\chap01\实例1\BorderLayoutDemo.java5752003-07-07codesc.net\[J2SE]应用编程150例\chap01\实例1\BoxLayoutFrame.class7262003-07-15code…

***突然断开可能是ADSL猫惹的祸

在我们使用服务器的时候&#xff0c;最讨厌的就是无故的断线了&#xff0c;可能正在和好一起副本&#xff0c;或者正在视频热聊中&#xff0c;还或者youtube视频看的正起劲&#xff0c;突然windows一个对话框弹出 - “连接已经断开”。实在是太影响体验了&#xff0c;断开之后&…

文件中数组的最大值及其对应的最小下标

2019年春季学期第二周作业基础作业请在第一周作业的基础上&#xff0c;继续完成&#xff1a;找出给定的文件中数组的最大值及其对应的最小下标&#xff08;下标从0开始&#xff09;。并将最大值和对应的最小下标数值写入文件。 输入&#xff1a;请建立以自己英文名字命名的txt文…

ceph bluestore源码分析:admin_socket实时获取内存池数据

环境&#xff1a; 版本&#xff1a;ceph 12.2.1 部署完cephfs 使用ceph-fuse挂载&#xff0c;并写入数据 关键参数&#xff1a; debug_mempool true 将该参数置为true即可查看详细的blustore管理的内存池的数据 命令&#xff1a; ceph daemon osd.id dump_mempools该命令为ad…

java clob内存溢出_java - java.sql.SQLException:ORA-01704:字符串文字太长时插入或更新 - 堆栈内存溢出...

通常&#xff0c;当我插入4000个字符限制时&#xff0c;它的工作正常&#xff0c;但当超过4000个字符时&#xff0c;它抛出SQL异常字符串文字太长&#xff0c;即使我的DISCHARGE_TEXT数据类型是CLOB我的JavaScript代码是function saveAsDraftNew(){var admissionNo document.g…

LC并联谐振回路

转载于:https://www.cnblogs.com/prayer521/p/4103091.html

zencart分类页产品页去掉url中的id号

最近公司新上的网站被seo指出要修改url&#xff0c;去掉url中产品id。由于我们用的是zencart框架&#xff0c;装了 Ultimate SEO URLs 插件&#xff0c;所以在网上应该有这方面的资料&#xff0c;本文主要参考资料&#xff1a;原网址&#xff1a;修改seo url中去掉产品id的方法…