前面讲过不少有故事背景的程序设计,但就知识点涉及层面还有所不足,所有,这个系列到目前为止还需更新,希望有兴趣的朋友们可以和我一起敲一敲,看看这些有背景的程序设计的实质到底是什么。
目录
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;
}
上面这个代码真的很漂亮,建议大家反复琢磨,反复研究,相信一定会有所收获。