输出形式:中文提示按照m个猴子,数n 个数的方法,输出为大王的猴子是几号 ,建立一个函数来实现此功能三.需求分析: 文章编辑:
1.文章录入:包含中英文,空格和各种字符;用函数shuchu()来实现. 2.文章的统计: 包含中英文字母.空格数和文章总字数的统计,用函数Tongjiwz()来实现.
3.字符统计:根据客户的需要,统计在文章任一字符出现的次数,用函数GetTime()来实现.
4.字符的删除: 根据客户的需要,把文章中出现的符合客户要求的全部删
除,用shanchu()来实现.
纸牌游戏:
用函数node()按照题目要求的规则,用几个循环体来实现.
猴子选大王:
首先用一个数组来存放猴子的编号,从1到m,然后用hzxdw()按题目要求,用两个双重循环来实现猴子大王的选举.
四.程序实现思想:
首先必须确定实现这个课程设计的主算法是使用链式存储结构还是栈又或是数组和广义表。 根据题目要求需要实现的功能有: 1、 数据录入:输入各种数据;
此处即创建链表的过程,调用一个成员函数负值。在此处还有一个方法实现,即先输入数据,然后再调用构造实现。 2、数据统计:
存储方式的选择,是使用链式存储结构还是栈又或是数组和广义表;遵守先定义后调用的原则;数组定义时注意下标的起始值和上限;链表定义时注意结点中的项;准确运用结点。 3、 数据输出:按要求的格式打印
调用do循环和for循环,通过遍历链表实现输出,用cout函数出。 4、 查找,修改,删除:
这三个功能的核心是寻找成员,先遍历链表,然后寻找对应的ID号来找到结点,然后再对结点实行删除,修改操作。
五.概要设计: 题目1:文章编辑
一 .算法思想
用顺序表来存放一篇文章,用指针*wz来录入文章,文章以#作为结束,然后统计文章各种数据,直到#号为止,查找用户要统计的和删除的字符都是一样的思想,删除某一子串,并将后面的字符前移。
题目2:猴子选大王
一、算法思想
将表中最后一个结点的指针域指向头结点,整个链表形成一个环,构造循环链表 ‘*L’。由此,从表中任意一个结点开始,都可以遍历全表。再用一个for循环来实现从第1开始数,第数到第N个,该猴子就要离开此圈。如果链表不空的话,用’a’指向开始结点,往后数到第N个结点,就把第N-1个结点与第N+1个结点链在一起,即实现了删除第N个结点。如此反复,直到L的后继结点是它自己,即圈中只剩最后一只猴子,那么这只猴子就是大王。 二、概要设计
1)、猴子的存放采用链式存储结构,利用循环链表来实现建立的,其表
示方法是递归定义的:
typedef struct Mnode { int data; struct Mnode *next;
}Mnode;
根据题目要求,要让这M只猴子顺序围坐一圈,那就得用循环链表,只须将单循环链表的尾指针的NEXT域指向头指针。它的判空条件是L=L->next =NULL;
(非空表) (空表)
单循环链表
2)、函数status Electe_King()读取数据M、N后,然后就根据N的值,用for循环数猴子结点用’a’指向开始结点,往后数到第N个结点,就把第N-1个结点与第N+1个结点链在一起,即实现了删除第N个结点。如此反复,直到L的后继结点是它自己,即圈中只剩最后一只猴王。其源代码如下:
for(int j=1;j<=N;j++)
{
L=L->next;
if(L->data!=L->next->data)
{ a=L->next;
L->next=L->next->next; L=L->next->next; delete a;
}
}
本算法只用了两个简单的for循环,所以时间复杂度为O(m )。其中
2
难点是如何实现数到第N就删除它。
题目3:纸牌游戏
纸牌游戏的算法思想与猴子选大王的大体上相似。
六.源代码:
#define chuqi 1000 #define zengjia 100 #include #include typedef struct{ char *wz; int length; int listsize; }sqlise;void Tongjiwz(char *wz,int zy,int kg,int zs)
{//统计文章各种数据的函数,wz代表文章,zy代表中英文字母数,kg代表空格数,zs代表文章总字数 char *p=wz; zy=kg=zs=0; while(*p!='@') {
if((*p>0x40&&*p<0x5B)||(*p>0x60&&*p<0x7B)) zy++;
if(*p==0x20) kg++; zs++; p++; }
cout<<\"统计完成!结果如下:\"<cout<<\"中英文字母数:\"<void GetTime(char* wz,char* p){//统计某一字符串在文章中出现的次数 char *a=wz,*temp=a,*b=p; int num=0,zj; while(*a!='@') {
temp=a; b=p;
while(*b!='#') {
if(*(temp++)==*(b++)) zj=1; else zj=0; }
if(zj)num++; a++; }
cout<void shanchu(char *wz,char *p) {//删除某一字符串char *a=wz,*temp=a,*b=p; int zj=0;
while(*a!='@') {
temp=a; b=p;
while(*b!='#') {
if(*(temp++)==*(b++)) zj=1;
else
zj=0;; }
if(zj) {
while(*temp!='@'&&(*(a++)=*(temp++))) *a='@';
cout<<\"删除字符串成功!\"<cout<<\"删除后的文章如下:\"<void shuchu(sqlise &L){//输入文章后输出文章 char n; int i=0; int m;L.wz=(char *)malloc(chuqi*sizeof(char)); if(!L.wz)cout<<\"存储分配失败!\"<cout<<\"ok!\"<L.listsize=chuqi; }cout<<\"请输入文章:\"<>n;while(n!='#') {
L.wz[i]=n; i++; cin>>n; m=i; }
cout<<\"你刚才输入的文章如下:\"<for(i=0;itypedef struct need{//纸牌游戏 int data; int tag; }need;void node(){
need park[52]; int i,j;
for(i=1;i<=52;i++){ park[i-1].data=i; park[i-1].tag=1; }
for(i=2;i<=52;i++){ for(j=i;j<=52;j++){
if(park[j-1].data%i==0)
park[j-1].tag=park[j-1].tag*(-1); } }
cout<<\"※※※※※※※※※※※※纸牌游戏结束时正面向上的牌有※※※※※※※※※※※※\"; cout<for(i=0;i<52;i++){if(park[i].tag==1){
cout<<\"※※※※※※※※※※※※※※※※※第\"; cout<void hzxdw(int m,int n)//猴子选大王 {int a[100];
int s=0,bj=m; //s作为n的标志 for(int i=0;ia[i]=i+1; //为猴子编号while(bj>1)//当bj=1时表明猴子大王已选到 {
bj=0;
for(i=0;iif(a[i]) s++;//记数; if(s==n)s=a[i]=0; //猴子离开此圈; if(a[i]) bj++; }
} for(i=0;icout<<\"猴子大王为:\"<<(i+1)<void main() { zcd:cout<<\"**********************************************\"<cout<<\"* 想进入文章编辑系统,请按1 *\"<cout<<\"* 想进行纸牌游戏, 请按2 *\"<cout<<\"* 想进行猴子选大王, 请按3 *\"<cout<<\"**********************************************\"<>m; if(m==1) {sqlise T;
char *n,*m,c[100],b[100]; int z,k,s,l,i; shuchu(T); pp:
cout<<\"**********************************************\"<cout<<\"*你要统计文章各种数据, 请按11 *\"<cout<<\"*统计某一字符串在文章中出现的次数,请按12 *\"<cout<<\"*你要删除某一字符串, 请按13 *\"<cout<<\"*提醒:想返回主菜单请按4 *\"<cout<<\"**********************************************\"<cout<<\" 欢迎进入文章编辑系统,你想做什么,请选择: \"<>l; switch(l) {case 11:Tongjiwz(T.wz,z,k,s);goto pp;break; case 12:cout<<\"输入你要统计的字符串:\"; for(i=0;i<100;i++) {
cin>>c[i];
if(c[i]=='#')break; } m=c;
GetTime(T.wz,m);goto pp;break; case 13:cout<<\"输入你要删除的字符串:\"; for(i=0;i<100;i++) {
cin>>b[i];
if(b[i]=='#')break; }
n=b;
shanchu(T.wz,n);goto pp;break; case 4: goto zcd;break; } }
else if(m==2)node(); else if(m==3) {
int zs,n1;
cout<<\"请输入猴子总数和规则中规定n的值:\"; cin>>zs>>n1; hzxdw(zs,n1); }
cout<<\"提醒:想返回主菜单请按4\"<>k;while(k==4) goto zcd; }
七.运行后的菜单展示
八、调试分析
(1)语法错误
语法错误相对来说要好调试一些的,但有两点需要特别指出:一是应该用规范化的格式输入源程序,我推荐的格式是:函数体内、循环体内等都应该缩进一个TAB位,相应的块语句的两个大括号都应保持在同一列上,函数体之间、模块之间都应用空行隔开,这就解决了各种匹配的问题,更重要的是它极大的增强的程序的可读性。二是应该注意函数的实参与形参的传递问题,要尽量保持两者类型的匹配,(当不匹配又可通过编译时会发生数据类型的隐式转换,这样会产生很多不安全且又很难找到的错误)当不需要改变形参时,只需传入变量,如果你想在函数体内改变函数的外部变量,则传入指针: (2)指针问题
如:char *name;再将name做为一个指针传到函数中,你的本意可能是想通过函数改变你的字符串,但这里你忽略了一个问
题,你没有初始化你的指针却用了它,这样很不安全,虽然你有时可以运行,却有了不安定的因素。你可以这样定义:char name[20];这里的name是一个常量地址,也是一个数组名,因此不用担心它没有被初始化。字符数组与字符串的区别是前者不用在最末位加一个’\\0’,但你如果把它当做字符串用时系统会自动给你加上的,因此在定义字符数组时尽量多定义一位) (3)注意中英文符号
如:中文的分号和英文的分号是不一样的,这是我在调试中最大的体会,害的我用了半个多小时呢!
九、课设总结:
要提高自己的编程能力,你必须亲自去体验、去设计、编辑、
编译、调试、运行。在此之前,我也以为自己对C语言已经比较懂了,可还是遇到了一系列问题,也学到很多东西。每一个人都是在失败、尝试、失败、尝试与收获中成长起来的。我本学识尚浅,无权谈论这些,只是希望能对大家有所警醒,编程之道漫漫无边,吾将上下而求索.当你看着自己把功能一个个实现,把错误一个调试出来,那种感觉给了自己某种安慰,还有自信!让自己对语言有了更深一层的了解!