POJ-2774 后缀数组基础题

本文详细解析了如何通过后缀数组解决POJ2774问题,即寻找两个字符串间的最长公共子串。文章通过具体代码展示了获取后缀数组及高度数组的过程,并最终确定最长公共子串的长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POJ 2774

题意:求两个字符串的最长公共子串。

总结:搞了半天还是不太理解,看着大神博客强行敲的。。而且还看到有hash+二分做的。

// POJ-2774
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<bitset>
#include<vector>
#include<set>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define F(i,a,b)  for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 3e5+10;

char str[N], str1[N];

//这些应该可以做模板了。。
int wa[N], wb[N], wsf[N], wv[N], sa[N];
int rankn[N], height[N], s[N];
int cmp(int *r, int a, int b, int k)
{
    return r[a]==r[b] && r[a+k]==r[b+k];
}
void Getsa(int *r, int *sa, int n, int m)
{
    int i, j, p, *x=wa, *y=wb, *t;
    F(i,0,m) wsf[i]=0;
    F(i,0,n) wsf[x[i]=r[i]]++;
    F(i,1,m) wsf[i]+= wsf[i-1];
    for(i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i;
    p=1, j=1;
    for( ; p<n; j*=2, m=p) {
        for(p=0, i=n-j; i<n; i++) y[p++]=i;
        F(i,0,n) if(sa[i]>=j) y[p++]=sa[i]-j;
        F(i,0,n) wv[i]=x[y[i]];
        F(i,0,m) wsf[i]=0;
        F(i,0,n) wsf[wv[i]]++;
        F(i,1,m) wsf[i]+= wsf[i-1];
        for(i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
        t=x, x=y, y=t;
        x[sa[0]]=0;
        for(p=1, i=1; i<n; i++)
            x[sa[i]]= cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
    }
}
void Getheight(int *r, int n)
{
    int i, j, k=0;
    FF(i,1,n) rankn[sa[i]]=i;
    F(i,0,n) {
        if(k) k--;
        else k=0;
        j=sa[rankn[i]-1];
        while(r[i+k]==r[j+k]) k++;
        height[rankn[i]]=k;
    }
}


int main()
{
    while(~scanf("%s%s", str, str1)) {
        int n=0, len=strlen(str);
        F(i,0,len) s[n++]= str[i]-'a'+1;
        s[n++]=28;
        len=strlen(str1);
        F(i,0,len) s[n++]= str1[i]-'a'+1;
        s[n]=0;    //把两个字符串并到一起,中间和结尾加上标识符

        Getsa(s, sa, n+1, 30);
        Getheight(s, n);
        int maxn=0, pos=0;
        len=strlen(str);
        F(i,2,n) if(height[i]>maxn) {   //找出一个height值最大并且i与i-1的sa值分别在两串字符中
            if(0<=sa[i-1] && sa[i-1]<len && len<sa[i])
                maxn=height[i];
            if(0<=sa[i] && sa[i]<len && len<sa[i-1])
                maxn=height[i];
        }
        printf("%d\n", maxn);
    }

    return 0;
}

 

转载于:https://www.cnblogs.com/sbfhy/p/6353298.html

内容概要:本文深入解析了扣子COZE AI编程及其详细应用代码案例,旨在帮助读者理解新一代低门槛智能体开发范式。文章从五个维度展开:关键概念、核心技巧、典型应用场景、详细代码案例分析以及未来发展趋势。首先介绍了扣子COZE的核心概念,如Bot、Workflow、Plugin、Memory和Knowledge。接着分享了意图识别、函数调用链、动态Prompt、渐进式发布及监控可观测等核心技巧。然后列举了企业内部智能客服、电商导购助手、教育领域AI助教和金融行业合规质检等应用场景。最后,通过构建“会议纪要智能助手”的详细代码案例,展示了从需求描述、技术方案、Workflow节点拆解到调试与上线的全过程,并展望了多智能体协作、本地私有部署、Agent2Agent协议、边缘计算插件和实时RAG等未来发展方向。; 适合人群:对AI编程感兴趣的开发者,尤其是希望快速落地AI产品的技术人员。; 使用场景及目标:①学习如何使用扣子COZE构建生产级智能体;②掌握智能体实例、自动化流程、扩展能力和知识库的使用方法;③通过实际案例理解如何实现会议纪要智能助手的功能,包括触发器设置、下载节点、LLM节点Prompt设计、Code节点处理和邮件节点配置。; 阅读建议:本文不仅提供了理论知识,还包含了详细的代码案例,建议读者结合实际业务需求进行实践,逐步掌握扣子COZE的各项功能,并关注其未来的发展趋势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值