四、仍然利用KMP算法实现字符串和目标串的匹配,先进行对初始密码的赋值并存储到文件中如图4-1,4-2,再将密码有效次数确定并且存储到文件中,如图4-3。第一次输入正确的密码,显示匹配成功,如图4-4。密码有效次数变化,如图4-5。再次输入正确的密码,却因为超过密码有效次数的变化而显示匹配失败,如图4-6。
#include <stdio.h>
#include <string.h>
// 定义最大字符串长度为20
#define Max_size 20
// 定义密码组数为3
#define N 3
// 定义宏,用于表示真值
#define true 1
// 定义宏,用于表示假值
#define false -1
// 记录密码有效次数
int time = 0;
// 定义二维数组,用于存储N组密码
char answer[N][Max_size];
// 定义数组,用于存储用户输入的密码
char keys[Max_size];
// 定义标志变量,用于记录是否匹配成功
int flag = false;
// 函数:计算模式串T的next数组
void Next(char *T,int *next)
{
int i = 1;// 从模式串的第二个字符开始计算next值
next[1] = 0;// 第一个字符的next值为0
int j = 0;// j用于记录匹配的长度
while(i < strlen(T) )// 遍历模式串T
{
if (j == 0 || T[i-1] == T[j-1])// 如果j为0或者当前字符匹配成功
{
i++;
j++;
next[i] = j;// 更新next值
}
else
j = next[j];// 如果不匹配,j回退到next[j]指向的位置
}
}
// 函数:KMP算法,用于在文本串S中查找模式串T
int KMP(char *S,char *T)
{
int next[Max_size];// 定义next数组
Next(T,next);//根据模式串T,初始化next数组
int i = 1;// 文本串S的指针
int j = 1;// 模式串T的指针
while (i <= strlen(S) && j <= strlen(T) )// 当两个指针都未越界时继续匹配
{
//j==0:代表模式串的第一个字符就和当前测试的字符不相等;S[i-1]==T[j-1],如果对应位置字符相等,两种情况下,指向当前测试的两个指针下标i和j都向后移
if ( j == 0 || S[i-1] == T[j-1] )// 如果j为0或者当前字符匹配成功
{
i++;
j++;
}
else// 如果不匹配,j回退到next[j]指向的位置
j = next[j];//如果测试的两个字符不相等,i不动,j变为当前测试字符串的next值
}
if(j > strlen(T) )// 如果j已经超过了模式串T的长度,说明匹配成功
{
return true;
}
else
return false;
}
void Use_time()
{
FILE *fp = fopen("E:\\C语言的软件\\数据结构与算法\\4\\密码次数.txt","r+");
fscanf(fp,"%d",&time);
fclose(fp);
}
void Save_time()
{
FILE *fp = fopen("E:\\C语言的软件\\数据结构与算法\\4\\密码次数.txt","w+");
fprintf(fp,"%d",time);
fclose(fp);
}
void Use_key()
{
int i = 0;
FILE *fp = fopen("E:\\C语言的软件\\数据结构与算法\\4\\密码.txt","r+");
while(!feof(fp))
{
fscanf(fp,"%s",answer[i]);
i++;
}
fclose(fp);
}
void FirstWelcome()
{
printf(" *****************************************\n");
printf(" *****************************************\n");
printf(" ***** *****\n");
printf(" ***** 欢迎使用密码锁小程序 *****\n");
printf(" ***** *****\n");
printf(" ***** 1.初始化密码 *****\n");
printf(" ***** *****\n");
printf(" ***** 2.输入密码 *****\n");
printf(" ***** *****\n");
printf(" ***** 3.退出程序 *****\n");
printf(" ***** *****\n");
printf(" *****************************************\n");
printf(" *****************************************\n");
}
void Init_key() //初始化密码
{
FILE *fp = fopen("E:\\C语言的软件\\数据结构与算法\\4\\密码.txt","w+");
for(int i = 0; i < N; i++)
{
printf("请输入初始化的第%d组密码\n",i+1);
scanf("%s",answer[i]);// 输入每组密码
fprintf(fp,"%s ",answer[i]);
}
fclose(fp);
printf("请输入初始化的密码有效次数:");// 存储密码有效次数
scanf("%d",&time);
Save_time();
}
void Input_key()
{
printf("请输入密码\n");
scanf("%s",keys);// 输入用户密码
}
void Contrast()// 比较
{
Use_time(); //查看初始化次数
Use_key(); //查看初始化密码
for(int j = 0; j < N; j++)
{
if( KMP(keys,answer[j]) == true && time > 0)// 使用KMP算法匹配密码
{
flag = true;
break;// 如果匹配成功,跳出循环
}
}
if(flag == true)
{
printf("密码匹配成功!");
time--;
Save_time();
}
else
printf("密码匹配失败!");
}
int main()
{
while(1)
{
FirstWelcome(); //界面
printf("请输入前面对应的序号进入对应的功能;");
char c = _getch();
switch (c)
{
case '1': //
printf("1\n");
Init_key(); //初始化密码
//程序暂停和清空控制台
system("pause");
system("cls");
break;
case '2': //
printf("2\n");
Input_key();
Contrast();
//程序暂停和清空控制台
system("pause");
system("cls");
break;
case '3': //
printf("3\n");
system("cls");
printf("Bye Bye!\n");
exit(0);
break;
default:
exit(0);
break;
}
}
return 0;
}





