设计程序,利用KMP算法实现密码锁中的虚位密码的判定,同时实现临时密码(输入有限次数后失效)的产生和验证

四、仍然利用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;
}
图4-1 密码初始化
图4-2 密码存储在文件
图4-3 密码有效次数存储在文件中
图4-4 密码匹配
图4-5 密码有效次数变动
图4-6 密码匹配失败

 

 

 

  • 21
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值