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

前面讲过不少有故事背景的程序设计,但就知识点涉及层面还有所不足,所有,这个系列到目前为止还需更新,希望有兴趣的朋友们可以和我一起敲一敲,看看这些有背景的程序设计的实质到底是什么。

目录

1.鞍点

2.凯撒加密

3.字数统计

4.字符串匹配


1.鞍点

若是在矩阵m*n中存在一个元素a[i][j](i<=i<=m,1<=j<=n);该元素是第i行元素的最小值且又是第j列元素的最大值,则称此元素为该矩阵的一个鞍点。求矩阵A的所有鞍点。

 这题只需要明白什么叫做矩阵的鞍点,问题就很容易解决。具体只需要我们先在矩阵中逐行查找该行的最小值,然后判断该元素是否是所在列的最大值,如果是所在列的最大值,输出该元素及所在行号和列号。

算法实现如下:

设函数AnDian在二维数组中查找所有鞍点。

1.初始化累加器count=0;

2.循环变量i从0~m-1,重复执行下述操作:

2.1在第i行中查找最小值元素a[i][k];

2.2如果元素a[i][k]是第k列的最大值,则输出元素a[i][k];count++;

2.3i++;

3.如果count=0,则矩阵无鞍点;

代码实现如下:

#include<stdio.h>

void AnDian(int arr[3][4],int m,int n);

int main()
{
	int arr[3][4]={
  {7,4,2,5},{8,7,6,9},{3,2,5,8}};
	AnDian(arr,3,4);
	return 0;
}

void AnDian(int arr[3][4],int m,int n)
{
	int i,j,k,min,count=0;
	for(i=0;i<m;i++)
	{
		min=arr[i][0];
		k=0;
		for(j=1;j<n;j++)
		{
			if(arr[i][j]<min)
			{
				min=arr[i][j];
				k=j;//第i行中最小元素的下标 
			}
		}	
		for(j=0;j<n;j++)
		{
			if(arr[j][k]>min)  
				break;
		}			
		if(j == n)
		{
			count++;
			printf("第%d个鞍点是(%d,%d)%d\n",count,i+1,k+1,arr[i][k]);
		}
	}
	if(count == 0)  
		printf("该矩阵中无鞍点\n");
}

 啊~~~裂开!上面代码用了好久时间检查错误(因为思路对了,但打印结果一样很抽象,结果同样代码换VS就正常运行,感觉Dev有问题,等后面研究研究再和大家分享吧!

2.凯撒加密

凯撒加密由朱迪斯·凯撒在其政府的秘密通信中使用而得名,其基本思想是:将待加密信息(称为明文)中每个字母在字母表中向后移动常量key(称为密钥),得到加密信息(称为暗文)。例如,假设字母表为英文字母表,key等于3,则将明文computer加密为frpsxwhu。

这种题的话就是了解题干所提供的信息,结合进行编程就好了。

算法实现如下:

设变量key表示密钥,函数Encrypt实现凯撒加密。

1.对明文中的每一个字符ch,执行下述操作:

1.1如果ch是大写字母,则ch='A'+(ch+key-'A')%26;

1.2如果ch是小写字母,则ch='a'+(ch+key-'a')%26;

2.返回密文

代码实现如下:

#include<stdio.h>

void Encrypt(char* str1,char*str2,int key)
{
	int i;
	for(i=0;str1[i]!='\0';i++)
	{
		if(str1[i]>='A'&&str1[i]<='Z')
			str2[i]='A'+(str1[i]+key-'A')%26;
		if(str1[i]>='a'&&str1[i]<='z')
			str2[i]='a'+(str1[i]+key-'a')%26;
	}
}
int main()
{
	char str1[100],str2[100];
	int key;
	printf("请输入你设置的密钥:");
	scanf("%d",&key);
	printf("请输入一个字符串:");
	fflush(stdin);//这里一定要加这个函数哦,不然结果会让你大吃一惊!
	gets(str1);
	printf("明文是:%s\n",str1);
	Encrypt(str1,str2,key);
	printf("暗文是:%s\n",str2);
	return 0;
}

 上面的代码基本功能能实现,即字母的解密能够实现,但倘若字符串中含有数字空白字符,就无法准确无误解密了😳

#include<stdio.h>

void Encrypt(char* str1,char*str2,int key)
{
	int i;
	for(i=0;str1[i]!='\0';i++)
	{
		if(str1[i]>='A'&&str1[i]<='Z')
			str2[i]='A'+(str1[i]+key-'A')%26;
		else if(str1[i]>='a'&&str1[i]<='z')
			str2[i]='a'+(str1[i]+key-'a')%26;
		else
			str2[i]=str1[i];
	}
	str2[i]='\0';//因为str1[i]='\0'时,退出循环,所以,我们应该手动在str2后面加一个'\0',避免打印字符串时系统越界,打印乱码。
}
int main()
{
	char str1[100],str2[100];
	int key;
	printf("请输入你设置的密钥:");
	scanf("%d",&key);
	printf("请输入一个字符串:");
	fflush(stdin);
	gets(str1);
	printf("明文是:%s\n",str1);
	Encrypt(str1,str2,key);
	printf("暗文是:%s\n",str2);
	return 0;
}
3.字数统计

字处理软件的字数统计功能可以对一篇文档统计字符数(计空格)和字符数(不计空格)。请模拟该功能,对一个字符串进行字符统计,分别统计包括空格和不包括空格的字符数(假设字符串少于80个字符)。

这题的话大家细品一下,和上面一题本质上是有相同点的。

算法实现如下:

设函数CharCount统计字符串str中包括空格的字符数count1和不包括空格的字符数count2。

1.对字符串中的每一个字符ch,执行下述操作:

1.1count1++;

1.2如果ch不是空格,则count2++;

2.返回count1和count2; 

代码实现如下:

#include<stdio.h>

void CharCount(char*str,int*p,int*q) 
{
	int i,count1=0,count2=0;
	for(i=0;str[i]!='\0';i++)
	{
		count1++;
		if(str[i]!='\40')
			count2++;
	}
	*p=count1;
	*q=count2;//两个需要返回的数,但是函数只有一个返回值,所以这里传了地址,从而达到改变两个变量的值 
}
int main()
{
	char ch[80];
	int countSum,countNospace;
	printf("请输入一个字符串:");
	gets(ch);
	CharCount(ch,&countSum,&countNospace);
	printf("字符数(计空格):%d\n",countSum);
	printf("字符数(不计空格):%d\n",countNospace);	
	return 0;
}
4.字符串匹配

给定一个主串s和一个模式(也称为子串)t,在主串s中寻找模式t的过程为字符串匹配,也称为模式匹配。如果匹配成功,则返回模式t中第一个字符在主串s中的序号。例如:模式"am"在主串"I am a student"中的序号是3。

这里大家仔细思考思考,其实是不是和解密也有一点相同:首先,我们肯定也要建立两个字符数组(用于存放主串和模式),然后我们需要对两个字符数组进行操作。不过,解密那里是把一个数组赋值给另一个,这里是判断是否相等。

算法实现如下:

设函数Cmp实现在主串s中查找模式t。

1.初始化主串s的起始位置下标i=0;初始化模式t的起始下标j=0;

2.初始化比较的起始位置start=0;

3.重复下述操作,直到s或t的所有字符比较完毕:

3.1如果s[i]=t[i],则继续比较主串s和模式t的下一对字符;

3.2将start后移一位,将i和j回溯,准备比较下一轮;

4.如果t中所有字符都比较完毕,则返回起始位置start对应的序号,否则,匹配失败,返回0;

 代码实现如下:

#include<stdio.h>

int Cmp(char*arrs,char*arrt)
{
	int i=0,j=0,start=0;
	while(arrs[i]!='\0'&&arrt[j]!='\0')
	{
		if(arrs[i]==arrt[j])
		{
			i++;
			j++;
		}
		else
		{
			start++;
			i=start;
			j=0;//这里是很好的一点,让j=0,就能有效避免第一个字符相同,后面不相同时,调整使模式再次从头开始。 
		}
	}
	if(arrt[j]=='\0') 
		return start+1;
	else
		return 0;
}
int main()
{
	char s[100],t[20];
	int index;
	printf("请输入主串:");
	gets(s);
	printf("请输入模式:");
	gets(t);
	index=Cmp(s,t);
	if(index==0)
		printf("匹配不成功!\n");
	else
		printf("匹配成功!%s在%s中的序号是:%d\n",t,s,index);
	return 0;
}

上面这个代码真的很漂亮,建议大家反复琢磨,反复研究,相信一定会有所收获。

相关推荐

  1. 有趣代码——故事背景程序设计4

    2023-12-06 22:18:02       35 阅读
  2. 计算机科学背后故事和挑战

    2023-12-06 22:18:02       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-06 22:18:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-06 22:18:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-06 22:18:02       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-06 22:18:02       20 阅读

热门阅读

  1. 怎么验证公钥和私钥是一对

    2023-12-06 22:18:02       48 阅读
  2. HTTP常见响应码

    2023-12-06 22:18:02       42 阅读
  3. QT配合CSS隐藏按钮

    2023-12-06 22:18:02       38 阅读
  4. 怎样做好信用卡汽车分期业务营销

    2023-12-06 22:18:02       44 阅读
  5. Ubuntu网络问题的解决

    2023-12-06 22:18:02       41 阅读
  6. 002_qml矩阵的使用方式

    2023-12-06 22:18:02       28 阅读
  7. ARM安全架构——为复杂软件提供保护

    2023-12-06 22:18:02       46 阅读