HDU 1403 Longest Common Substring(最长公共前缀)

http://acm.hdu.edu.cn/showproblem.php?pid=1403

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

思路:

刚开始学后缀数组,确实感觉很难,但是这东西很强大,所以必须要学会它,推荐罗穗骞大牛的论文。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn=200000+5;
16
17 char s[maxn],s1[maxn];
18 int sa[maxn],t[maxn],t2[maxn],c[maxn],n;
19 int Rank[maxn],height[maxn];
20
21 void build_sa(int m)
22 {
23     int *x=t,*y=t2;
24     //基数排序
25     for(int i=0;i<m;i++)    c[i]=0;
26     for(int i=0;i<n;i++)    c[x[i]=s[i]]++;
27     for(int i=1;i<m;i++)    c[i]+=c[i-1];
28     for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
29     for(int k=1;k<=n;k<<=1)
30     {
31         int p=0;
32         //直接利用sa数组排序第二关键字
33         for(int i=n-k;i<n;i++)  y[p++]=i;
34         for(int i=0;i<n;i++)    if(sa[i]>=k)    y[p++]=sa[i]-k;
35         //基数排序第一关键字
36         for(int i=0;i<m;i++)    c[i]=0;
37         for(int i=0;i<n;i++)    c[x[y[i]]]++;
38         for(int i=1;i<m;i++)    c[i]+=c[i-1];
39         for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
40         //根据sa和y计算新的x数组
41         swap(x,y);
42         p=1;
43         x[sa[0]]=0;
44         for(int i=1;i<n;i++)
45             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
46         if(p>=n)
47             break;
48         m=p;                //下次基数排序的最大值
49     }
50 }
51
52 void getHeight()
53 {
54     int i,j,k=0;
55     for(i=1;i<=n;i++)  Rank[sa[i]]=i;
56     for(i=0;i<n;i++)
57     {
58         if(k)  k--;
59         int j=sa[Rank[i]-1];
60         while(s[i+k]==s[j+k])  k++;
61         height[Rank[i]]=k;
62     }
63 }
64
65 int main()
66 {
67     //freopen("in.txt","r",stdin);
68     while(~scanf("%s",s))
69     {
70         int len = strlen(s);
71         s[len]=‘0‘;
72         scanf("%s",s+len+1);
73         n=strlen(s);
74         build_sa(128);
75         getHeight();
76         int ans=0;
77         for(int i=1;i<n;i++)
78         {
79             if(height[i]>ans)
80             {
81                 if((sa[i]>len && sa[i-1]<len) || (sa[i]<len && sa[i-1]>len))
82                     ans=height[i];
83             }
84         }
85         printf("%d\n",ans);
86     }
87     return 0;
88 }
时间: 2024-10-09 22:54:03

HDU 1403 Longest Common Substring(最长公共前缀)的相关文章

HDU 1403 Longest Common Substring(后缀数组,最长公共子串)

hdu题目 poj题目 参考了 罗穗骞的论文<后缀数组——处理字符串的有力工具> 题意:求两个序列的最长公共子串 思路:后缀数组经典题目之一(模版题) //后缀数组sa:将s的n个后缀从小到大排序后将 排序后的后缀的开头位置 顺次放入sa中,则sa[i]储存的是排第i大的后缀的开头位置.简单的记忆就是“排第几的是谁”. //名次数组rank:rank[i]保存的是suffix(i){后缀}在所有后缀中从小到大排列的名次.则 若 sa[i]=j,则 rank[j]=i.简单的记忆就是“你排第几”

HDU - 1403 - Longest Common Substring

先上题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4010    Accepted Submission(s): 1510 Problem Description Given two strings, you have to tell the length of the Long

leetcode——Longest Common Prefix 最长公共前缀(AC)

Write a function to find the longest common prefix string amongst an array of strings. 其实做起来会感觉很简单,需要注意的是要考虑效率的问题,毕竟可能是很长的字符串数组,所以可以考虑选取所有字符串中最短的那个来首先进行比较,因为最长公共子串肯定不会大于其长度,这样避免了字符串之间长度差异很大造成的效率损失,然后每次比较之后最长公共子串的长度也永远不会大于最短的那个字符串,只会不变或减小,只要遍历字符串数组,挨个

HDU 1403 Longest Common Substring(后缀数组啊 求最长公共子串 模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1403 Problem Description Given two strings, you have to tell the length of the Longest Common Substring of them. For example: str1 = banana str2 = cianaic So the Longest Common Substring is "ana", a

lintcode 中等题:longest common substring 最长公共子串

题目 最长公共子串 给出两个字符串,找到最长公共子串,并返回其长度. 样例 给出A=“ABCD”,B=“CBCE”,返回 2 注意 子串的字符应该连续的出现在原字符串中,这与子序列有所不同. 解题 注意: 子序列:这个序列不是在原字符串中连续的位置,而是有间隔的,如:ABCDE  和AMBMCMDMEM 最长公共子序列是ADCDE 子串:子串一定在原来字符串中连续存在的.如:ABCDEF 和SSSABCDOOOO最长公共子串是ABCD 参考链接,讲解很详细 根据子串定义,暴力破解 public

# Leetcode 14:Longest Common Prefix 最长公共前缀

公众号:爱写bug Write a function to find the longest common prefix string amongst an array of strings. If there is no common prefix, return an empty string "". 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". Example 1: Input: ["flower"

leetcode Longest Common Prefix 最长公共前缀 (python)

Write a function to find the longest common prefix string amongst an array of strings. class Solution: # @return a string #最长公共前缀 def longestCommonPrefix(self, strs): if strs is None or strs ==[]:return '' result ='' pre =None for cur in xrange(len(s

LeetCode Longest Common Prefix 最长公共前缀

题意:给多个字符串,返回这些字符串的最长公共前缀. 思路:直接逐个统计同一个位置上的字符有多少种,如果只有1种,那么就是该位是相同的,进入下一位比较.否则终止比较,返回前缀.可能有一个字符串会比较短,所以前缀最长也只是最短字符串的长度. 1 class Solution { 2 public: 3 string longestCommonPrefix(vector<string>& strs) { 4 string ans=""; 5 if(strs.empty()

[LeetCode]32. Longest Common Prefix最长公共前缀

Write a function to find the longest common prefix string amongst an array of strings. 解法:从所有的string的头到尾的字母逐一比较即可. class Solution { public: string longestCommonPrefix(vector<string>& strs) { int n = strs.size(), i = 0; bool flag = false; if (n =