算法设计与分析——第一篇,写在前面的话
来源:互联网 发布:易思普软件 编辑:程序博客网 时间:2024/06/05 11:39
写在前面的话——
做程序员也有几年了,一直以来都是在有需要的时候,上网查查资料,看看别人写的博客来充实自己,有时候也会想写写随笔,学习笔记什么的,可是空空如也的我,一直以来都没有什么可以写的,不过既然决定重新回到学校,开始一段新的历程,那就还是写写吧,正好学校也开了算法设计与分析这门课,每节课后,老师都会要求写一篇当堂课的相关论文报告交上去,我就把我的每篇作业贴上来吧,不过都是参考书上的东西!
第一篇——
第一次作业比较简陋,主要是对一些简单的题目,写出一个基本的代码,加上一些分析
1, 求1000以内的完数
设计思想:完数的定义为该数的所有真因子之和仍等于其本身,由此可以预先排除掉数字1,而后需要求出所有大于1的数的所有真因子并且求和,当和为其本身的时候,该数为完数。
#include <stdio.h> int main(){ intn = 1000; inti; for(i= 2; i <= n; i++) { intj; intsum = 0; for(j= 1; j < i; j++) { if(0== i % j) {//求出所有的真因子 sum+= j;//求出真因子后进行求和 } } if(sum== i) {//若所有真因子之和和该数相等,则该数为完数 printf("%d为完数\n",i); } } return 0;}
2, 求一个输入的正整数的分化数目
设计思想:根据整数划分的思想,设函数Q(n,m)表示整数n的划分中最大加数为m的数目,可以得知:
(1)Q(n,1) =Q(1,m) = 1,因为无论是1的分划还是对于被加数最大为1,其都只有一种分划,即为n个1相加
(2)当n<m时,Q(n,m)=Q(n,n),因为被加数m显然不会超过n
(3)Q(n,m) =Q(n,m-1) + Q(n-m,m),Q(n,m-1)表示Q(n,m)中不包含m的划分,而Q(n,m)中包含m的划分可以通过对n-m进行不超过m的划分数目来取得
(4)当n=m时可以作为(3)的特殊情况,即Q(n,n)= Q(n,n-1) + 1
根据以上结论可以通过递归法求出结果
#include <stdio.h> int Division(int n, int m){ if(n < 1 || m < 1) { return 0; } else if (n == 1 || m == 1) {//Q(n,1) = Q(1,m) = 1 return 1; } else if ( n < m) { return Division(n , n); } else if ( n == m) { return Division(n , n - 1) + 1;//Q(n,n) = Q(n,n-1)+ 1 } else { returnDivision(n , m - 1) + Division(n - m , m);//Q(n,m) = Q(n,m-1) + Q(n-m,m) }} int main(){ int n; printf("输入需要分化的整数:"); scanf("%d",&n); int num = Division(n, n); if(0 == num) { printf("输入错误!\n"); } else { printf("%d的分划数目为%d\n",n ,num); } return 0;}
关于上面特别标了颜色的那条,也就是这个Q(n,m) =Q(n,m-1) + Q(n-m,m),当时百思不得其解,后来想通了,就是这个意思,可以理解为,Q(n,m)这个数字是由两部分组成,Q(n,m-1)代表Q(n,m)中不包含m的部分,那么剩下的就是仅包含m的部分,根据各种百度的说法,所谓求Q(n,m) 中仅包含m的部分,就是求Q(n-m,m),这个以我的能力非常不好解释,只能说看你能不能想到,简单来说,我就是找一个实例,分析,比如Q(6,4),那么4开头的项,是4+2和4+1+1,你可以想到,其实这个数目就是数字2的分划的数目,在看所谓Q(n,m)的m开头的项,其实就是m+(n-m),观察这个项,其实就是左边是m,右边就是n-m的分划,左边都是一样的,而右边的数目就是n-m分划的数目,所以整个是数目就是n-m的分划的数目,这个应该可以理解了吧,但是这个应该只是一种情况,就是Q(n,m)的m项的数目=Q(n-m,n-m),但是我们可以看到,实际上应该是等于Q(n-m,m),那么这个里面还有什么差别呢,呃,我没有研究,所以上面只是启发了一下大概的思考方向,如果要具体弄清楚,要么就是用数学的方法,要么就是找一些实例来验证,找到规律,我就不多说了!
3,分别使用递归和循环来实现输入一个任意十进制正整数,从低位到高位输出各位上的数字,再实现从高位到低位输出各位上的数字
设计思想:讲一个十进制正整数分拆开得到每一位的数字,首先可以通过对10取余得到个位的数字,然后通过除以10,去掉最后一位,再重复上一步,最终可以得到每一位的数字,但是如果使用循环法,因为不知道确切位数,直接求出最高位再依次得到低位比较麻烦,可以通过从低往高求出各位的数字再通过循环逆向输出,所以使用循环法会用到两次循环,但是如果使用递归法,可以通过调整递归调用和输出函数的位置来实现正向或逆向输出。
使用循环(从低位到高位):
#include <stdio.h> int main(){ intn,index = 1; printf("输入一个十进制正整数:"); scanf("%d",&n); if(n< 0) { printf("输入错误!\n"); return0; } while(n> 10) { printf("第%d位数字是%d\n",index ,n%10);//通过对10取余取出该位的数字 n= n/10;//由于是整型,通过除以10达到降低位数的目的 index++; } printf("第%d位数字是%d\n",index ,n%10); return 0;}
从高位到低位:
#include <stdio.h> int main(){ intn,index = 1,a[100] = {0}; printf("输入一个十进制正整数:"); scanf("%d",&n); if(n< 0) { printf("输入错误!\n"); return0; } while(n> 10) { a[index]= n%10; n= n/10; index++; } a[index]= n%10; inti; for(i= index; i > 0; i--) { printf("第%d位数字是%d\n",i,a[i]); } return 0;}
使用递归从低位到高位:
#include <stdio.h> void Division(int n){ if(n< 10) { printf("最高位为%d\n",n); }else { printf("%d\n",n%10); Division(n/10); }} int main(){ intn,index = 1,a[100] = {0}; printf("输入一个十进制正整数:"); scanf("%d",&n); if(n< 0) { printf("输入错误!\n"); return0; } Division(n); return 0;}
从高位到低位:
#include <stdio.h> void Division(int n){ if(n< 10) { printf("最高位为%d\n",n); }else {s Division(n/10);//先递归,待逐级返回之后再打印输出,从而实现从高位到低位 printf("%d\n",n%10); }} int main(){ intn,index = 1,a[100] = {0}; printf("输入一个十进制正整数:"); scanf("%d",&n); if(n< 0) { printf("输入错误!\n"); return0; } Division(n); return 0;}
上面这个题,其实很简单,其实想想,就是循环与递归的对比,从低位到高位输出的时候,没什么太大的区别,但是高位到低位顺序输出的时候,循环方法明显会麻烦一点,所以也体现了一个题选择合适的算法会提高效率避免无意义的循环!
- 算法设计与分析——第一篇,写在前面的话
- 我的第一篇博客——写在前面的话
- 第一篇博文——写在前面的话
- PureTalk.算法与数据结构——写在前面的话
- 写在第一篇的话
- 第一天: 写在前面的话
- 《算法设计与分析基础》学习笔记-0-写在前面
- 写在设计模式前面的话
- 写在前面——第一篇原创博客
- Thinking——写在前面的话
- Android教程——写在前面的话
- 写在博客第一篇的话
- Java设计模式(写在前面的话)
- 写在HBase源码分析前面的话
- 算法系列博客之写在前面的话
- CMAPI实战攻略——写在前面的话(提纲)
- 写在前面的话——中国ISV生存现状调查
- 写在前面的话——Introduction to Algorithms Third Edition
- 游戏服务器开发都要学什么
- QTP - 描述性编程
- spring之bean的配置细节
- spring AspectJ的Execution表达式
- Dinic网络流(我的模板+注释)
- 算法设计与分析——第一篇,写在前面的话
- 计算机图形学 学习笔记(一):光栅图形学算法:直线扫描算法(DDA,中点画线算法,Bresenham算法)
- vim下的ctags和taglist等的使用和配置
- RTMP协议发送H.264/AAC编码数据
- 打造完美的ImageLoader——LruCache+DiskLruCache
- ShapeFile数据到mongodb的导入
- BIOS警报声
- Java面向对象编程(3)--抽象类,接口,final
- Error: libcudart.so.7.5: cannot open shared object file: No such file or directory