8591 计算next值

原题描述

Description
编写算法,录入多个字符串计算并验证NEXT值,输入0结束。
输入格式
第一行:输入n,表示有n个需计算NEXT值的字符串
第二至n+1行:每行输入一个字符串

输出格式
第1至第n行:通过计算每相应行的字符串得出的NEXT值

输入样例
4
abcdefg
aaaaab
abaabcac
aaabaaab

输出样例
NEXT J is:0111111
NEXT J is:012345
NEXT J is:01122312
NEXT J is:01231234

题目分析

题目具体算法就不分析了,太多了,可以看书自行理解。最重要的就是递推式next[ i]=next[ i-1]+1,当然next[ i-1]的含义很关键。在前缀后缀连续匹配时,递推式中的next[ i-1]就是next[ i-1] ;当不匹配时,(假设有数组a[n])要将a[ i-1 ]与a[ next[ i-1] ] 匹配,若成功,则说明前缀a[1]a[2]…a[ next[ i-1] 与以a[ i-1 ]为末尾且前缀等长的后缀匹配,这种情况下递推式中next[ i-1]就是next[ next[ i-1] ] 。若仍不匹配,则需循环上述动作(就是代码中的while循环),直至next [ n ]等于0,说明在 i 前面的串中没有任何长度大于等于1的相同的前缀和后缀。根据书本95页定义此时next[ i]=1,或者也相当于next [ i-1]就是0。
PS:套娃真的恶心!书本用的是严蔚敏数据结构C语言版第二版。
在这里插入图片描述

代码

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

void nx(char a[])
{
    int i,j,len=strlen(a+1),next[105]={0};/*因为字符串是从1开始的,
                                            所以这里所有操作也要从1开始*/
    for(i=2;i<=len;i++)
    {
        j=next[i-1];
        while(j&&a[i-1]!=a[j])
            j=next[j];
        next[i]=j+1;       //递推式next[i]=next[i-1]+1的更新版
    }
    printf("NEXT J is:");
    for(i=1;i<=len;i++)//输出next函数
        printf("%d",next[i]);
    printf("\n");
}

int main()
{
    int i,n;
    char a[105][105]={0};
    cin>>n;
    getchar();
    for(i=0;i<n;i++)
        gets(a[i]+1);//规定字符串都是从1开始存放有效字符
    for(i=0;i<n;i++)
        nx(a[i]);
    return 0;
}

总结

整个代码中就是短短几行(11行至17行)实现了上面我用接近两百字描述的算法。个人认为这类代码实现能力是很值得我们学习的(思想来自老师,代码自己复现)。有必要来捋一捋别人是怎么写出这些代码的。
先按最正常的情况来,在前缀后缀连续匹配时,递推式中的next[ i-1]就是next[ i-1] ,可以很自然写出13和16行代码。在无法连续匹配时(即a[ i-1 ]!=a[ next[ i-1]),对应的算法部分可以转换成14行的while循环,此时循环条件中没有 j !=0。直到最后,a[ i-1 ]与前面的匹配全部失败,按照定义,本来应该在16行后面直接补充一条条件赋值语句(if(j==0)next[ i]=1 else next[ i]=j+1;)。但我们应该看到当j等于0,14行的while循环将会永远进行下去,所以我们将j为真值补充进循环控制条件里。这样就写出了我们看到的短小精悍的代码。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值