接着上篇文章再和大家分享一下有趣的代码!
目录
1.求母串中子串的个数
2.行走机器人
3.荷兰国旗问题
4.统计考研成绩
1.求母串中子串的个数
给定一个母串s和一个子串t,在主串s中寻找子串t的过程为字符串匹配。每匹配成功一次,即母串中含有一个子串,求母串中子串的个数。
其实,这个题目的关键有两点:①如何在母串中查找子串并计数 ?②查找后怎么进行下一次查找?具体方法在这里也不详细讲了,大家可以看下面这篇文章中第四题,那段代码能方便大家了解,而这题的代码也是在那段基础之上改进的。
有趣的代码——有故事背景的程序设计4-CSDN博客文章浏览阅读340次,点赞13次,收藏6次。前面讲过不少有故事背景的程序设计,但就知识点涉及层面还有所不足,所有,这个系列到目前为止还需更新,希望有兴趣的朋友们可以和我一起敲一敲,看看这些有背景的程序设计的实质到底是什么。目录1.鞍点2.凯撒加密3.字数统计4.字符串匹配https://blog.csdn.net/m0_74950144/article/details/134819294?spm=1001.2014.3001.550
算法实现如下:
设函数CmpNum实现在母串s中查找子串t,设变量count表示母串中含子串的个数。
1.初始化母串s的起始位置下标i=0;初始化子串t的起始下标j=0;
2.初始化比较的起始位置start=0;
3.重复下述操作,直到s的所有字符比较完毕:
3.1如果s[i]=t[i]
3.1.1继续比较母串s和子串t的下一对字符;
3.1.2如果t[i]='\0',则j=0,start=i,count++;
3.2将start后移一位,将i和j回溯,准备比较下一轮;
4.如果s中所有字符都比较完毕,则返回count;
代码实现如下:
#include<stdio.h>int CmpNum(char*arrs,char*arrt)
{int i=0,j=0,start=0,count=0;while(arrs[i]!='\0')//直接循环到arrs数组结束,这样才能查找母串中所有子串{if(arrs[i]==arrt[j]){i++;j++;if(arrt[j]=='\0'){j=0;count++;//arrt结束一次,则代表含有一个子串start=i;//一个子串结束,那么start也应该调整到其后面,从而减少程序的无用功}}else{start++;i=start;j=0;//这里是很好的一点,让j=0,就能有效避免第一个字符相同,后面不相同时,调整使模式再次从头开始。 }}return count;
}int main()
{char s[100],t[20];int index;printf("请输入母串:");gets(s);printf("请输入子串:");gets(t);index=CmpNum(s,t);printf("母串中含子串个数:%d",index);return 0;
}
2.行走机器人
假设在平面直角坐标系内,机器人每次可以前进或后退一步、向左或向右行走一步。请模拟机器人控制系统中指令的翻译和执行过程,并给出机器人的行走路线。
在平面直角坐标系中想描述机器人的行走路线,我们肯定是要用(x,y)坐标来表示机器人的行进位置。我们可以定前进一步,位置坐标为(x+1,y),后退一步为(x-1,y),向左一步(x,y-1),向右一步到达(x,y-1)。
算法实现如下:
设变量command表示一条行走指令,函数Move模拟指令的翻译和执行系统。
1.获取机器人当前位置(x,y);
2.指令command可能存在以下四种情况:
①前进:到达位置(x+1,y);
②后退:到达位置(x-1,y);
③向左:到达位置(x,y-1);
④向右:到达位置(x,y-1);
代码实现如下:
#include<stdio.h>int x = 0 , y = 0 ;//全局变量哦
enum Direction
{forward = 1,back,left,right
};void Move(enum Direction command)
{switch(command){case forward:x++;break;case back:--x;break;case left:++y;break;case right:--y;break;default:break;}
}int main()
{enum Direction command;int i , temp ;printf("请输入机器人的动作,用空格分隔\n");printf("以下为指令:\n1.前进 2.后退 3.向左 4.向右\n");printf("当前位置为(%d , %d)\n", x , y );while(scanf("%d",&temp)!=0){command = (enum Direction)temp;Move(command);printf("-->(%d , %d)\n", x , y );}return 0;
}
这道题其实单从代码的复杂度来说并不难做,只是题目背景是在有点新颖,不过,涉及的枚举类型的创建和枚举变量的定义倒是值得大家研究研究。另外,这里定义全局变量x,y有偷懒的意思,不过,这样使函数内x,y都能联系起来,方便我们处理。
3.荷兰国旗问题
重新排列一个由红,黄和蓝(这三种即是荷兰国旗的颜色)构成的数组,使得所有的红色都在最前面,白色在其次,蓝色在最后。
首先,这种红黄蓝作为数组元素的题目,我们当然可以很自然地和枚举类型或者字符型联系起来,在这里我们定义一个枚举类型。设数组arr[N]存储Red、White和Blue,设置三个参数i、j、k,其中i之前的元素全为(不包括arr[i])全部为红色;k之后的元素(不包括arr[k])全部为蓝色;i和j之间的元素全部为白色;j表示从前向后扫描。首先,将i初始化为0,k初始化为n-1;j初始化为0。j从前向后扫描,在扫描过程中根据arr[j]的颜色,将其交换到序列的前面或后面,当j=k时,算法结束。
算法实现如下:
设数组arr[N]有Red、White和Blue三种元素,函数Sort实现荷兰国旗问题。
1.初始化i=0,k=n-1,j=0;
2.当j<=k时,依次考查元素arr[j],有以下三种情况:
2.1如果arr[j]是Red,则交换arr[i]和arr[j];i++;j++;
2.2如果arr[j]是Blue,则交换arr[j]和arr[k];j++;k--;
2.3如果arr[j]是White,则j++;
代码实现如下:
#include<stdio.h>#define N 8enum Color{Red,White,Blue
};void Sort (enum Color*a, int n);
/*留心观察的会发现我一般函数直接定义,很少先声明后定义,因为比较懒,
这里之所以先声明把定义放在后面,是因为两个函数的定义会比较长,那样
主函数的部分就太靠后,不便于观察,大家谨记!*/void Print(enum Color*a, int n);int main()
{enum Color a[N]={White,Red,Blue,Red,Blue,White,Red};Sort(a,N);printf("排序后的序列为:");Print(a,N);return 0;
}void Sort (enum Color*a, int n)
{int i=0,k=n-1,j=0;enum Color temp;while(j<k){switch(a[j]){case Red:temp = a[i];a[i] = a[j];a[j] = temp;i++;j++;break;case Blue:temp = a[j];a[j] = a[k];a[k] = temp;k--;break;case White:j++;break;}}
}void Print(enum Color*a, int n)
{int i = 0;for(i=0;i<n;i++)switch(a[i]){case Red: printf("Red ");break;case Blue: printf("Blue ");break;case White:printf("While ");break;}
}
这题的设计实在是有些妙的,因为这题定义两个变量i,k作为两端,某种意义上来说,这属于双指针在数组中查找,极大地提高了代码的效率。
4.统计考研成绩
在计算机专业考研中,专业课考试科目包括数据结构、计算机组成原理、操作系统和计算机网络。对于一个考生,输入各科成绩,并计算总分。
因为这里一个考生的四门专业课成绩以及总分都与他有内在联系,所以我们在这里为了解决这种较为复杂的数据元素,理应构造结构体类型。
算法实现如下:
设变量totalScore存储考生的总分,变量spec1、spect2、spect3和spect4分别存储四科专业课的成绩。
1.输入一个考生的各项信息;
2.totalScore=spec1+spec2+spec3+spec4;
3.输出totalScore;
代码实现如下:
#include<stdio.h>struct Student
{char no[10],name[10];double spec1,spec2,spec3,spec4;
};int main()
{struct Student stu;double totalScore;printf("请输入考生的考号和姓名:\n");scanf("%s%s",stu.no,stu.name);printf("请输入四门专业课成绩,用空格分隔:\n");scanf("%lf%lf%lf%lf",&stu.spec1,&stu.spec2,&stu.spec3,&stu.spec4);totalScore=stu.spec1+stu.spec2+stu.spec3+stu.spec4;printf("%s的总分是%5.1f\n",stu.name,totalScore);return 0;
}