中南大学程序设计基础实践报告由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“中南大学程序设计报告”。
中南大学
程序设计基础实践报告
题 目 基本知识单项训练 学生姓名 LZJ 指导教师 穆 帅 学 院 信息科学与工程学院 专业班级 计算机科学与技术 完成时间 2014年1月10日
目录
第一章 设计目的........................................................1 第二章 设计内容及过程..................................................1 2.1 汉诺塔程序.........................................................1 2.1.1设计目标.......................................................1 2.1.2数据结构设计...................................................1 2.1.3主要算法说明...................................................2 2.2冒泡法排序及其改良..................................................3 2.2.1设计目标.......................................................3 2.2.2数据结构设计...................................................4 2.2.3主要算法说明...................................................4 2.3选择法排序及其改良..................................................5 2.3.1设计目标.......................................................5 2.3.2数据结构设计...................................................6 2.3.3主要算法说明...................................................6 2.4统计字母出现的频率..................................................7 2.4.1设计目标.......................................................7 2.4.2数据结构设计...................................................7 2.4.3主要算法说明...................................................7 2.5实现一个程序的多次调试..............................................8
第三章 运行结果........................................................9 3.1 汉诺塔程序运行情况.................................................9 3.2 两种冒泡法的结果及耗时对比........................................11 3.3 两种选择法的结果及耗时对比........................................13 3.4统计字符出现的频率运行结果.........................................14 第四章 总结...........................................................15 4.1 本次程序设计所遇到的问题及解决过程................................15 4.2 从课程设计得到的感悟..............................................17 致 谢.................................................................17 附录..................................................................17 参考文献..............................................................23
第一章 设计目的进一步加深、巩固所学专业课程《C语言程序设计》的基本理论知识,理论联系实际,进一步培养自己综合分析问题和解决问题的能力。掌握运用C语言独立地编写、调试应用程序和进行其它相关设计的技能。具体来说:
一.掌握以“汉诺塔程序”为典例的递归思想的运用。
二.学会灵活使用“冒泡法”和“选择排序法”等排序方法,并且通过探索,将各种方法进一步改良,提高程序运行的效率。
三.通过对以“统计字母出现的频率”的程序设计,掌握二维数组的赋值,各字符个数,所有字符的总个数等算法。四.经过这几个单项训练,提高自己的综合编程能力,为今后开发高难度的程序打下良好的基础。
第二章 设计内容
2.1 汉诺塔程序
2.1.1设计目标
用递归方法实现汉诺塔程序,显示盘子的移动次数和移动过程,盘子总数可作为程序参数在运行程序时输入。
汉诺塔是个古老而又经典的游戏,在用程序实现它之前,我们可以先了解一下相关信息与集体规定。
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
2.1.2数据结构设计
本小程序使用的数据类型是主要为整型。定义变量时,部分代码如下:
void f(int num,int t1,int t2, int t3,int &cishu)
盘子个数 整型 int num; 第一个塔 整型 int t1;第二个塔 整型 int t2;第三个塔 整型 int t3;盘子移动的次数 整型 int cishu;
2.1.3主要算法说明
1.递归思想
如果不使用递归方法进行思维,这个问题会让人摸不着头绪。如果运用递归方法,就会变得简单。
首先,我们了解一下什么是递归调用思想。
递归调用是一种特殊的嵌套调用,是某个函数调用自己,而不是另外一个函数。递归调用一种解决方案,一种是逻辑思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50块石头,他想,只要先搬走49块,那剩下的一块就能搬完了,然后考虑那49块,只要先搬走48块,那剩下的一块就能搬完了„„,递归是一种思想,只不过在程序中,就是依靠函数嵌套这个特性来实现了。
2.递归思想在汉诺塔程序中的具体运用
接下来,我们看看如何将递归思想运用到汉诺塔程序中。
若只有一个盘子,则是直接从第一个塔t1移动号到第三个塔t3(这就是这个函数的递归出口);
若有一个以上的盘子时(设为n个),则考虑一下的步骤:(1).借助第三个塔,将n-1盘子从第一个塔t1移到第二个塔t2;(2).将剩余的最大的盘子由第一个塔t1直接移到第三个塔 t2;
(3).借助第一个塔,将第二个塔t2上的n-1盘子移到第三个塔t3;(4.)反复进行以上操作,直到剩下最后一个盘子,到达递归出口。
3.主要函数的具体解析 该程序中运用到的自定义函数为
void f(int num,int t1,int t2, int t3,int &cishu)1 2
此为汉诺塔核心函数; 3
(1)用if(num==1)
(2)用else{} 计算盘子数目num大于1的情况;
(3)在main()函数中,用scanf()获取想要移动的盘子的总个数num,然后调用自定义函数f(),用printf()输出“执行过程”与“移动次数cishu”。
4.网络上类似算法的展示:
{printf(“%d-> %dn”,t1,t3);cishu++;}作为函数的递归出口;
其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1(有兴趣的可以自己证明试试看)。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;
若n为奇数,按顺时针方向依次摆放 A C B。
⑴按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
⑵接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
⑶反复进行⑴⑵操作,最后就能按规定完成汉诺塔的移动。所以结果非常简单,就是按照移动规则向一个方向移动盘子: 如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C
2.2 冒泡法排序及其改良
2.2.1设计目标
冒泡法排序:叙述冒泡法排序和改进冒法泡排序的基本思想,用程序实现这两种排序算法,输入多组数据进行测试,统计对比这两种排序算法的排序耗时,并说 3
明这种结果出现的原因。
2.2.2数据结构设计
本程序主要使用数据类型为数组类型和整型类型,具体如下:
存放一系列随机数字 整型数组 长度为200 int a[200] 形参 整型数组 int b[]; 形参 整型 int k;
要排列的数字个数 整型 int m; 循环所用的变量 整型 int i,j;交换两个数字的中间量 整型 Int t, 有没有发生交换的标志 整型Int biaozhi;
2.2.3主要算法说明
1.冒泡法的主要思想
相邻两个数比较,若前面数打,则两数交换位置,直到最后一个元素被处理,最大的元素“沉”到下面,从而完成排序。这样如有n个元素,共进行n-1趟,每趟让剩余元素中最大的元素“沉到”下面,从而完成排序。
2.冒泡法的改良思想
事实上,n-1趟是最多的排序趟数,而只要在某一趟的排序中没有进行一次元素交换,说明已经排好序,可以提前退出外循环。如此一来,就减少了循环的次数,从而提高的程序的执行效率。3.程序中主要函数的解析(1)核心函数Maopao()用外循环for(j=0;j
用内循环for(i=0;i
4
(3)biaozhi的具体解释: 如果有交换,biaozhi=1,继续循环;
如果没有交换,biaozhi=0不变,用break提前结束循环。(4)在main()函数中,用scanf()获取想要排列的数字的个数; 用printf()输入排序后的元素。
4.改良前与改良后的两个程序的具体原因分析
两个程序中排序是由自定义的maopao()函数实现的,其中数组b[]没有说明长度,而是通过另一形参k来决定实参与形参数组元素结合的个数(简单来说就是排序的元素是几个由自己决定,通过scanf()来获取),由于数组名作为函数参数时,传递的是数组的起始地址,形参与实参共用相同的存储区域,maopao()函数中将b数组排好序,也就是将a排好序。
改良的程序通过增加变量biaozhi来实现改良效果,具体如下:(1)如果有交换,biaozhi=1,继续循环;
(2)如果没有交换,biaozhi=0不变,用break提前结束循环。
如此一来,减少了循环次数,提高程序执行效率。
2.3选择法排序及其改良
2.3.1设计目标
选择法排序:叙述选择法排序和改进选择法排序的基本思想,用程序实现这两种排序算法,输入多组数据进行测试,统计对比这两种排序算法的排序耗时,并说明这种结果出现的原因。
2.3.2数据结构设计
本程序主要使用数据类型为数组类型和整型类型,具体如下: 存放一系列随机数字 整型数组 长度为200 int x[200] 要排列的数字个数 整型 int n; 循环所用的变量 整型 int a,b;始终存放本趟最小元素的下标 整型 int k;交换两个数字的中间量 整型 Int t, 5
2.3.3主要算法说明 1.选择法的基本思想
选择法的基本思想是:先将第一个元素作为最小者,与后面元素比较,如第一个元素大,则与其交换(保证第一个元素总是最小的),直到与最后一个元素比较晚,第一趟就找出了最小元素,且保存在第一个元素位置。再以第二个元素作为最小者(次小)与后面元素比较,若后面元素下,则交换,直到最后一个元素,第二小的元素已找到。依此类推。经过n-1趟后排定。2.选择法的改良思想
事实上,只要记住比较时小元素的位置,即下标,在内循环结束后做一次交换即可,从而提高程序执行的效率。3.具体函数的解析
本程序仅使用了主函数main()(1)用第一个循环for(a=0;a
外层循环for(a=0;a
(3)内层循环 for(b=a+1;b
(4)用for(a=0;a
经过对测试结果(详情见下章运行结果)分析,第二个改良的程序效率明显比原来的程序高效得多,第二个程序中与第一个程序的不同点如下: for(a=0;a
6
if(x[k]>x[b])k=b;/*记住新的小元素的序号,在内循环结束后才和最后一个数实现交换*/ if(k!=a){ t=x[a];/*若k不等于i,说明a[i]不是最小的数,需要交换*/ x[a]=x[k];x[k]=t;} 变量K记住比较时小元素的位置,即下标,在内循环结束后做一次交换即可,从而提高程序执行的效率。
2.4 统计各字母出现的频率
2.4.1设计目标
统计字符出现的频率:二维字符数组中保存了很多字母,运行程序,计算各个字母出现的频率(频率=出现的次数/总字母数),并将频率显示出来。
2.4.2数据结构设计
本程序主要使用数据类型为数组类型和整型类型,具体如下: 存放一系列随机字母的字符型二维数组 int s[10][10];存放的所有字母的总个数 浮点型 float n; 循环所用的变量 整型 int i,j;表示26个大写字母的各个次数的数组 整型 int da[26];表示26个小写字母的各个次数的数组 整型 int xiao[26];
2.4.3主要算法说明
(1)gets(s[0]);调用gets()函数计算获取字母;(2)
n=strlen(s[0]);调用strlen函数,计算整个二维数组的字母总个数;(3)
用外循环for(i=0;i
内循环 for(j=0;j
如果 if(s[i][j]>='A'&&s[i][j]
如果else if(s[i][j]>='a'&&s[i][j]
7
对应的小写字母的次数自加一次 xiao[s[i][j]-'a']++;
(4)最后再用一个for循环输出运行结果 for(k=0;k
//k+'A'为大写字母,da[k]为此字母的个数;n为总字母数 if(xiao[k]!=0)printf(“%c的个数为:%dn 出现频率为:%f n”,k+'a',xiao[k],xiao[k]/n);//k+'a'为小写字母,xiao[k]为此字母的个数;n为总字母数
}
2.5实现一个程序的多次调试
最简单的算法说明:
在主函数中增加如下一部分,可实现这样的功能:
运行程序时,若输入任意键,则程序开始正式进行;并且可以输入多组数据进行调试,最后按Ctrl+Z(记得加回车)可以结束程序。char x;8 printf(“请输入任意键开始程序,若输入Ctrl+Z则结束程序n”);while(scanf(“%c”,&x)!=EOF){ /*所要运行的步骤的内容*/};
第三章 运行结果
3.1 汉诺塔程序运行情况 9
注:以上图片分别实现了盘子数为2,3,5时的汉诺塔程序的执行过程;
同时也展示了2.5中所提到的功能
“在主函数中增加如下一部分,可实现这样的功能:
运行程序时,若输入任意键,则程序开始正式进行;并且可以输入多组数据进行调试,最后按Ctrl+Z(记得加回车)可以结束程序。” 10
3.2 两种冒泡法的结果及耗时对比 11 12
注:此为第一种冒泡法方法的某次截图。
输入200个随机数字,经过5次试验取平均值,成功排序的时间大约1.1秒;输入相同的随机数据:改良后的冒泡法成功排序平均时间为0.8秒。提高了不少的效率。13
3.3 两种选择法的结果及耗时对比 14
注:以上截图为第一种选择排序法方法的某次截图。
输入150个随机数字,经过5次试验取平均值,成功排序的时间大约0.9秒;输入相同的随机数据:改良后的选择法成功排序平均时间为0.6秒。提高了不少的效率。
3.4统计字符出现的频率运行结果 15
注:以上截图为分别两次输入一系列无序列大小写字母后,计算出来的字母总个数,每个字母的个数和频率。
第四章 总结
4.1 本次程序设计所遇到的问题 1.怎么把递归思想运用到汉诺塔程序中?
刚开始我只了解递归出口是当盘子数目为1时,盘子由第一个塔移动到第三个塔,但是不知道当为n时应该怎么递归,因为这么普通的简单递归函数如: 16
f(n)=5*f(n-1)还是有一定的区别的;
经过对课本的重新翻阅,我加深了对汉诺塔的理解,知道了递归的实现是要通过三步,首先是n-1个盘子借助第三个塔移到第二个塔,再把第一个塔剩下的最大的盘子移到第三个塔,然后,我们还要借助第一个塔,把n-1个盘子移到第三个塔;
如此一来,重复下去,就能实现递归的思想了。
2.冒泡法和选择法的区别在于哪里?
起初,我对这两个方法以及两个方法的改良版有点混淆,只知道它们都是实现一系列随机数字的有序排列。
然而,经过对这四个不同程序的认真分析和设计,我逐渐明白了:
冒泡法是在相邻连个数之间进行比较,每趟把最大的数字放到最后面,如此循环下去(第二趟是第二大的数放到倒数第二个,依此类推)。
而改良后的冒泡法是把这些数字进行比较的同时,用一个biaozhi=0或1判断数字是否发生了交换(也就是是否已经排好了),若没有发生交换,则跳出循环,这样就减少了循环的次数,提高了效率。
选择法则是从第一个数开始,与后面的每一个数做比较,每比较一次,把小的数交换到第一个数的位置;(第二趟是把第二小的数放到第二个数的位置,依此类推);
而改良后的选择法则是在第一个数字与后面的数字都比较后,最后再交换一次。
3.二维数组如何赋值,使用?
第一次写 int s[10][10];gets(s);strlen(s);发现都有错误,程序无法通过;
经过反复测试,依然无法解决。后来我突然想起二维数组的地址问题,才知道s代表的是二维数组名,数组的首地址,无法直接赋值;
于是我尝试了用s[0],也就是第0行第0列的元素地址替换s;程序成功运行。17
4.2 从课程设计得到的感悟
经过一个星期的上机实践学习,使我对c语言有了更进一步的认识和了解,达到了课程设计起初的设计目的掌握以“汉诺塔程序”为典例的递归思想的运用。
学会灵活使用“冒泡法”和“选择排序法”等排序方法,并且通过探索,将各种方法进一步改良,提高程序运行的效率。
通过对以“统计字母出现的频率”的程序设计,掌握二维数组的赋值,各字符个数,所有字符的总个数等算法。
提高自己的综合编程能力,为今后开发高难度的程序打下良好的基础。
当然,我也体会到,要想学好C语言等编程语言,重在实践,要通过不断的上机操作才能更好地学习它,通过实践,我也发现我的一些不足之处,比如基本的二维数组的使用还不够熟练,不仅仅是学习c语言,还是其它的语言,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己便好地学好计算机。
[致谢] 首先,感谢廖胜辉老师对C语言的基本知识的教导,让我对C语言的程序算法的制定,基本程序语句,选择结构,循环结构,函数与编译预处理,数组,指针,构造数据类型等知识有了基本的掌握;
此外,我还要感谢王建新教授,在他的新生课上,我们学到了冒泡法,选择法,贪心法,穷举法等一系列编程思想,这对我们有很大的启蒙指导作用;
最后,我要感谢课程设计指导老师穆帅的悉心指导,在他的帮助下,我能学会独立地思考一些算法,学会如何改进程序。在回答他的提问中,我也进一步提升自己的专业知识的口头表达能力。此外,在写课程设计的报告过程中,我也学到了写报告的严谨性和规范性,这对我以后写其他报告会有很大的帮助,十分感激。
[附录] /*1.汉诺塔程序*/ #include void f(int num,int t1,int t2, int t3,int &cishu)/*num为盘子个数,t1代表第一个塔,t2代表第二个塔,t3代表第三个塔,cishu代表盘子移动的次数*/ { if(num==1){ 18
printf(“%d-> %dn”,t1,t3);/*递归出口*/ cishu++;} else {
f(num-1,t1,t3,t2,cishu);
/*借助第三个塔,将n-1盘子从第一个塔移到第二个塔*/
printf(“%d-> %dn”,t1,t3);
/*将剩余的最大的盘子由第一个塔直接移到第三个塔*/
cishu++;
/*每移动一次盘子,cishu 的值加1*/
f(num-1,t2,t1,t3,cishu);
/*借助第一个塔,将第二个塔上的n-1盘子移到第三个塔*/ } } main(){ int num;char x;printf(“请输入任意键开始程序,若输入Ctrl+Z则结束程序n”);while(scanf(“%c”,&x)!=EOF)
{
printf(“请输入盘子个数:n”);scanf(“%d”,&num);int cishu=0;printf(“执行过程如下:n”);f(num,1,2,3,cishu);printf(“移动次数为: %dn”,cishu);} }
/*2.1冒泡法*/
#include main(){ int a[200];int i,m;19
char x;printf(“请输入任意键开始程序n”);while(scanf(“%c”,&x)!=EOF){ void maopao(int b[],int k);/*声明实现排序的函数 */ void shuchu(int b[],int k);/*声明一个输出函数 */ printf(“n输入要排序的元素的个数:n”);scanf(“%d”,&m);printf(“n输入对应的元素:n”);for(i=0;i
scanf(“%d”,&a[i]);maopao(a,m);/* 调用函数*/ shuchu(a,m);} } void maopao(int b[],int k){ int i,j,t,biaozhi;for(j=0;j
for(i=0;i
if(b[i]>b[i+1])/*相邻元素交换位置*/
{
t=b[i];
b[i]=b[i+1];
b[i+1]=t;
}
} } void shuchu(int b[],int k)/*定义一个,输出函数*/ { int i;
for(i=0;i
if(i%10==0)
puts(“n”);/*每到十个数,换行 */
printf(“%6d”,b[i]);} puts(“n”);} /*2.2冒泡法改良*/ #include 20
main(){ int a[200];int i,m;void maopao(int b[],int k);/*声明实现排序的函数 */ void shuchu(int b[],int k);/*声明一个输出函数 */ char x;printf(“请输入任意键开始程序n”);while(scanf(“%c”,&x)!=EOF){
printf(“n输入要排序的元素的个数:n”);scanf(“%d”,&m);printf(“n输入对应的元素:n”);for(i=0;i
scanf(“%d”,&a[i]);maopao(a,m);/* 调用函数*/ shuchu(a,m);} } void maopao(int b[],int k){ int i,j,t,biaozhi;for(j=0;j
biaozhi=0;
for(i=0;i
if(b[i]>b[i+1])/*相邻元素交换位置*/
{
t=b[i];
b[i]=b[i+1];
b[i+1]=t;
biaozhi=1;/* 如果有元素的交换,biaozhi为1*/
}
if(biaozhi==0)/*如果没有交换,结束循环 */
break;} } void shuchu(int b[],int k)/*定义一个,输出函数*/ { int i;for(i=0;i
if(i%10==0)21
}
puts(“n”);/*每到十个数,换行 */ printf(“%6d”,b[i]);} puts(“n”);/*3.1选择法*/ #include main(){ int a,b,t,n;int x[200];char z;printf(“请输入任意键开始程序n”);while(scanf(“%c”,&z)!=EOF){ printf(“请输入要排序的元素的个数n:n”);scanf(“%d”,&n);
printf(“请输入%d个随机数字:n”,n);for(a=0;ax[b]){ t=x[a];x[a]=x[b];x[b]=t;} printf(“用第一种选择法排序后:n”);for(a=0;a main(){ int k,a,b,t,n;int x[200];char z;printf(“请输入任意键开始程序n”);while(scanf(“%c”,&z)!=EOF){ 22
printf(“请输入要排序的元素个数:n”);scanf(“%d”,&n);printf(“请输入%d个随机数字:n”,n);for(a=0;ax[b])k=b;/*记住新的小元素的序号,在内循环结束后才和最后一个数实现交换*/ if(k!=a){ t=x[a];/*若k不等于i,说明a[i]不是最小的数,需要交换*/ x[a]=x[k];x[k]=t;} } printf(“用第二种选择法排序后:n”);for(a=0;a #include main(){ char s[10][10];printf(“请输入一系列随机字母:n”);
gets(s[0]);//调用gets()函数计算获取字母
float n;
printf(“%sn”,s);
n=strlen(s[0]);//调用strlen函数,计算整个二维数组的字母总个数;
printf(“字母的总个数为:n%fn”,n);int j,i,k, da[26]={0},xiao[26]={0};//每个大写字母的个数da[k]表示,小写字母为xiao[k], 23
// 下文通过 k+'A 得到对应的字母
//da[0]对应大写A的个数;da[1]代表B的个数,以此类推
for(i=0;i
for(j=0;j
if(s[i][j]>='A'&&s[i][j]
da[s[i][j]-'A']++;//da[k]对应的字母k+'A'出现一次,则+1
else if(s[i][j]>='a'&&s[i][j]
xiao[s[i][j]-'a']++;} printf(“结果如下:nn”);
for(k=0;k
if(da[k]!=0)
printf(“%c的个数为:%dn 出现频率为:n”,k+'A',da[k],da[k]/n);
//k+'A'为大写字母,da[k]为此字母的个数;n为总字母数
if(xiao[k]!=0)
printf(“%c的个数为:%dn 出现频率为:n”,k+'a',xiao[k],xiao[k]/n);
//k+'a'为小写字母,xiao[k]为此字母的个数;n为总字母数
} }
[参考文献] [1]李丽娟,马淑萍.C语言程序设计.中国铁道出版社,103-104,134-135.[2]谭浩强.C语言程序设计.清华大学出版社,149-155.[3]百度文库.递归思想的解析
[4]严涛.Visual C++ 2008 程序设计简明教程.清华大学出版社,30-55
24%f %f
中南大学计算机实践报告......
中南大学本科生课程设计(实践)设计报告 (程序设计基础) 题目 MFC课程设计学生学号学生姓名指导教师学院专业班级计算机基础教学实验中心 2015年06月 14日一、引言MFC(Microso......
中南大学本科生课程设计(实践)任务书、设计报告(大学计算机基础)题 目 理想世界 学生姓名 李杰 指导教师 邵自然 学 院 湘雅医学院 临床医学与医学技术专业班级 1105班学生......
中南大学本科生课程设计(实践)任务书,设计报告(大学计算机基础)题 目:武侠世界 学生姓名:张泽指导老师:温国海学 院:粉末冶金研究院 专业班级:材化1401班学生学号:0702140109......
中南大学计算机实践报告中南大学计算机实践报告一.任务内容要想制作好一个网页,首先要在整体上规划好自己网站的主题和内容,确定自己需要传达给访问用户的主要信息,然后仔细斟......