mike_code 2023-08-05 22:43 采纳率: 33.3%
浏览 5
已结题

【C++】扩展KMP算法的模版代码出错

我的代码改了很久,还是不对。
所有报错都在第二行,也就是扩展KMP数组有问题,请帮忙找一下错误,谢谢!
原题链接:扩展KMP
代码如下:

#include <bits/stdc++.h>
using namespace std;
string s1,s2;
long long nxt[20000001],exkmp[20000001];
int main()
{
    cin>>s1>>s2;
    //nxt[i]:s2本身与以s2[i]开头的s2的后缀的LCP(最长公共前缀) 
    nxt[0]=s2.size();
    int k=1,p,l;
    for(int i=0;i+1<s2.size();i++)
    {
        if(s2[i]==s2[i+1])
            nxt[1]++;
        else break;
    }
    for(int i=2;i<s2.size();i++)
    {
        p=k+nxt[k]-1;
        l=nxt[i-k];
        if(l<=(p-i+1)-1)
        {
            nxt[i]=l;
        }
        else
        {
            int j;
            for(j=max(0,p-i+1);j+i<s2.size();j++)
            {
                if(s2[j]!=s2[j+i])
                    break;
            }
            nxt[i]=j;
            k=i;
        }
    }
    //exkmp:s2本身与以s1[i]开头的s1的后缀的LCP(最长公共前缀)
    k=1;
    for(int i=0;i<s2.size()&&i<s1.size();i++)
    {
        if(s2[i]==s1[i])
            exkmp[0]++;
        else
            break;
    }
    for(int i=1;i<s1.size();i++)
    {
        p=k+exkmp[k]-1;
        l=exkmp[i-k];
        if(l<=(p-i+1)-1)
        {
            exkmp[i]=l;
        }
        else
        {
            int j;
            for(j=max(0,p-i+1);j+i<s1.size()&&j<s2.size();j++)
            {
                if(s2[j]!=s1[j+i])
                    break;
            }
            exkmp[i]=j;
            k=i;
        }
    }
    //ans
    long long ans=0;
    for(int i=0;i<s2.size();i++)
        ans^=(i+1)*(nxt[i]+1);
    printf("%lld\n",ans);
        
    ans=0;
    for(int i=0;i<s1.size();i++)
        ans^=(i+1)*(exkmp[i]+1);
    printf("%lld",ans);
    return 0;
}
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-08-06 08:25
    关注

    【以下回答由 GPT 生成】

    【C++】扩展KMP算法的模版代码出错

    问题分析:

    根据你提供的代码,可以看出在扩展KMP算法的实现过程中有一些问题。代码实现的过程没有严格按照扩展KMP算法的步骤进行,导致程序的逻辑出现错误。具体问题如下:

    1. nxt数组计算错误:在计算nxt数组时,代码中使用nxt[1]存储相邻字符相等的数量。然而,这个计算方式是错误的。根据扩展KMP算法的定义,nxt[i]表示s2本身与以s2[i]开头的s2的后缀的LCP(最长公共前缀)。正确的计算方式应该是从右往左遍历,比较s2[i]和s2[i+1]之间的关系,当二者相等时,nxt[i] = nxt[i+1] + 1,并且将k指针重新定位到i位置。

    2. exkmp数组计算错误:在计算exkmp数组时,代码中使用exkmp[0]存储相邻字符相等的数量。然而,这个计算方式也是错误的。根据扩展KMP算法的定义,exkmp[i]表示s2本身与以s1[i]开头的s1的后缀的LCP(最长公共前缀)。正确的计算方式应该是从右往左遍历,比较s2[j]和s1[i+j]之间的关系,当二者相等时,exkmp[i] = exkmp[i+1] + 1,并且将k指针重新定位到i位置。

    解决方案:

    基于以上分析,以下是修正后的代码:

    #include <bits/stdc++.h>
    using namespace std;
    string s1, s2;
    long long nxt[20000001], exkmp[20000001];
    
    int main()
    {
        cin >> s1 >> s2;
        // nxt[i]: s2本身与以s2[i]开头的s2的后缀的LCP(最长公共前缀)
        nxt[s2.size() - 1] = s2.size();
        int k = s2.size() - 1, p, l;
        for (int i = s2.size() - 1; i > 0; i--)
        {
            if (s2[i] == s2[i - 1])
                nxt[i - 1] = nxt[i] - 1;
            else
                break;
        }
        for (int i = s2.size() - 2; i >= 0; i--)
        {
            p = k - nxt[k] + 1;
            l = nxt[i - k];
            if (l <= (i - p))
            {
                nxt[i] = l;
            }
            else
            {
                int j;
                for (j = max(0, p); j + i < s2.size(); j++)
                {
                    if (s2[j] != s2[j + i])
                        break;
                }
                nxt[i] = j;
                k = i;
            }
        }
        // exkmp: s2本身与以s1[i]开头的s1的后缀的LCP(最长公共前缀)
        k = s2.size() - 1;
        for (int i = 0; i < s2.size() && i < s1.size(); i++)
        {
            if (s2[i] == s1[i])
                exkmp[0]++;
            else
                break;
        }
        for (int i = 1; i < s1.size(); i++)
        {
            p = k - exkmp[k] + 1;
            l = exkmp[i - k];
            if (l <= (i - p))
            {
                exkmp[i] = l;
            }
            else
            {
                int j;
                for (j = max(0, p); j < s2.size(); j++)
                {
                    if (s2[j] != s1[j + i])
                        break;
                }
                exkmp[i] = j;
                k = i;
            }
        }
        // 其他代码...
    }
    

    请尝试使用修正后的代码再次进行测试,查看问题是否解决。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月8日
  • 创建了问题 8月5日

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看