设计程序,利用KMP算法实现密码锁中的虚位密码的判定

三、利用KMP算法进行字符串之间的匹配,先定义一个计算模式串的next数组,通过遍历模式串来记录next值和匹配长度达到记录前缀和后缀。通过KMP算法的两个指针相继往后走(不回溯),来实现模式串和文本串的匹配,结果如图3-1和3-2。

#include <stdio.h>
#include <string.h>
// 定义最大字符串长度为20  
#define Max_size 20  
// 定义密码组数为3  
#define N 3  
// 定义宏,用于表示真值  
#define true 1  
// 定义宏,用于表示假值  
#define false -1  

// 函数:计算模式串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;
}

int main()
{
    // 定义二维数组,用于存储N组密码
    char answer[N][Max_size];
    for(int i = 0; i < N; i++)
    {
        printf("请输入初始化的第%d组密码\n",i+1);
        scanf("%s",answer[i]);// 输入每组密码
    }
    char keys[Max_size];// 定义数组,用于存储用户输入的密码
    printf("请输入密码\n");
    scanf("%s",keys);// 输入用户密码

    int flag = false;// 定义标志变量,用于记录是否匹配成功
    for(int j = 0; j < N; j++)
    {
        if( KMP(keys,answer[j]) == true )// 使用KMP算法匹配密码
        {
            flag = true;
            break;// 如果匹配成功,跳出循环
        }
    }
    if(flag == true)
        printf("密码匹配成功!");
    else
        printf("密码匹配失败!");
    return 0;
}
图3-1 密码匹配失败结果图
图3-2 密码匹配成功结果图

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值