通过一个小程序(关于因式分解的)的体会
题目1:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5
这看似简单的题目,因为以前编过一个与它有点关系的:
题目2:判断101-200之间有多少个素数,并输出所有素数。当时我很快就把它搞定了:
#include<stdio.h> #include<math.h> main() { int i,j,t=0; for(i=101;i<=200;i++) { for(j=2;j<=(int)sqrt((double)i);j++) //注意sqrt()函数的参数类型 { if(i%j==0) { break; } else { if(i%j!=0&&j==(int)sqrt((double)i)) { printf("%d ",i); t++; break; } } } } printf("/n%d/n",t); }
,但到我这里却费了不少劲!
我刚开始想让让它结构化程度高点,但是我花了二十来分钟是把它写出来了,调试时没有error,但是有2个warn.我也没管它(我就不把它贴出来了)。但运行时,就是没结果。我想了半天感觉是函数之间接口的问题(虽然当时考二级C时把教材看了3遍,历年真题也都做了,但离一个真正程序员应具备的素质相差还是很远,函数接口没搞好,就说明自己还是没彻底掌握指针、函数部分的知识)。我又调试了大概半小时还是没有结果。最后我决定还是先别追求结构化了,先解决了问题再说。我参照刚写的(虽然有问题),改了改后:
#include<stdio.h> #include<math.h> #define M 50 main() { int a,b,c,t,i,j,n,k,d[M]; j=0; scanf("%d",&a); b=a; for(i=2;i<=(int)sqrt(a);i++) //判断是否是素数,除数从2到(int)sqrt(a) { //就够了,没必要到(a-1) if(a%i==0) { t=1; break; } else { if(a%i!=0&&i==(int)sqrt(a)) { t=0; break; } } } if(t==1) { c=a/2; //这里分解因式时除数只到(int)sqrt(a) for(i=2;i<=c;) //是不行的,比如21=3*7,除数只到 { //(int)sqrt(21)=4肯定不对,但到(a-1) k=a%i; //也没必要,到(a/2)即可! if(k==0) { d[j++]=i; a=a/i; //这里a的值是分解到一个 } //因子后,剩下的。 else { i++; } } } else { if(t==0) { j=2; d[0]=1; d[1]=a; } } printf("%d=",b); for(n=0;n<j-1;n++) { printf("%d*",d[n]); } printf("%d/n",d[j-1]); //控制输出时最后一个因子要单独输出,不然后 } //面会对一个乘号‘*’这样就对了。自己本以为这样很好,比如算法复杂度减小了很多,输出时也做了相应的控制。但是我看到答案时,我傻眼了:
程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成: (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。 (2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n, 重复执行第一步。 (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。 程序代码: #include<stdio.h> main() { int n,i; printf("Please input a number:/n"); scanf("%d=",&n); printf("%d=",n); for(i=2;i<=n;i++) { while(n!=i) { if(n%i==0) { printf("%d*",i); n=n/i; } else break; } } printf("%d/n",n); }
至少直观上只从代码量上看,比我写的少多了,最主要的是,本以为自己的算法考虑的比较周全,看了答案的分析才知道自己差了的很远。刚开始还想把它结构化程度高点,现在才发现被自己想复杂了,我也知道结构化很好,但就只针对这题而言,完全没必要把输入部分,分解部分,输出部分,分别放在不同的函数中,因为这只是一个很小的小程序,这不是工程文件!
通过做这个题感觉自己离一个真正的程序员相差太远!自己还应该把数据结构,指针,数组,函数部分反复学习,反复操练!