有趣的代码——有故事背景的程序设计5

接着上篇文章再和大家分享一下有趣的代码!

目录

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

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

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

#define N 8

enum 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

 这题的设计实在是有些妙的,因为这题定义两个变量i,k作为两端,某种意义上来说,这属于双指针在数组中查找,极大地提高了代码的效率。

4.统计考研成绩

在计算机专业考研中,专业课考试科目包括数据结构、计算机组成原理、操作系统和计算机网络。对于一个考生,输入各科成绩,并计算总分。

因为这里一个考生的四门专业课成绩以及总分都与他有内在联系,所以我们在这里为了解决这种较为复杂的数据元素,理应构造结构体类型。

算法实现如下:

设变量totalScore存储考生的总分,变量spec1、spect2、spect3和spect4分别存储四科专业课的成绩。

1.输入一个考生的各项信息;

2.totalScore=spec1+spec2+spec3+spec4;

3.输出totalScore;

代码实现如下:

#include

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;
}

你可能感兴趣的:(有趣的代码,c语言,开发语言,青少年编程,蓝桥杯,算法)