Longest Common Substring II(字尾自動機求多個串的最長公共子串)
A string is finite sequence of characters over a non-empty finite set Σ.
In this problem, Σ is the set of lowercase letters.
Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.
Now your task is a bit harder, for some given strings, find the length of the longest common substring of them.
Here common substring means a substring of two or more strings.
Input
The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.
Output
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Example
Input:alsdfkjfjkdsal fdjskalajfkdsla aaaajfaaaa Output: 2
之前用kmp寫過類似的題,估計這個鐵定超,,
在一個串上建sam,然後開始掃,lcs表示當前串匹配到這個結點時和sam上串的最大公共子串長度,nlcs表示前n個的
ac程式碼
#include<stdio.h> #include<stdlib.h> #include<string.h> #define max(a,b) (a>b?a:b) #define N 300010 struct sam { sam *pre,*son[26]; int len,lcs,nlcs; }que[N],*root,*tail,*b[N]; int tot; void add(int c,int l) { sam *p=tail,*np=&que[tot++]; np->len=np->nlcs=l; tail=np; while(p&&p->son[c]==NULL) { p->son[c]=np; p=p->pre; } if(p==NULL) np->pre=root; else { sam *q=p->son[c]; if(p->len+1==q->len) np->pre=q; else { sam *nq=&que[tot++]; *nq=*q; nq->len=nq->nlcs=p->len+1; np->pre=q->pre=nq; while(p&&p->son[c]==q) { p->son[c]=nq; p=p->pre; } } } } char str[N>>1]; int cnt[N>>1],len; void build() { int i,j; root=tail=&que[tot++]; for(i=0;i<len;i++) add(str[i]-'a',i+1); memset(cnt,0,sizeof(cnt)); for(i=0;i<tot;i++) cnt[que[i].len]++; for(i=1;i<=len;i++) cnt[i]+=cnt[i-1]; for(i=0;i<tot;i++) b[--cnt[que[i].len]]=&que[i]; } int main() { int i; scanf("%s",str); len=strlen(str); build(); while(scanf("%s",str)!=EOF) { sam *p=root; int l=0,i; for(i=0;str[i];i++) { int now=str[i]-'a'; if(p->son[now]) { l++; p=p->son[now]; } else { while(p&&p->son[now]==NULL) { p=p->pre; } if(p==NULL) { l=0; p=root; } else { l=p->len+1; p=p->son[now]; } } if(l>p->lcs) p->lcs=l; } for(i=tot-1;i>=0;i--) { p=b[i]; if(p->lcs<p->nlcs) p->nlcs=p->lcs; if(p->pre&&p->pre->lcs<p->lcs) p->pre->lcs=p->lcs; p->lcs=0; } } int ans=0; for(i=0;i<tot;i++) { if(que[i].nlcs>ans) ans=que[i].nlcs; } printf("%d\n",ans); }
相關推薦
Longest Common Substring II(字尾自動機求多個串的最長公共子串)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor
2018.12.15【SPOJ-LCS2】Longest Common Substring II(字尾自動機SAM)
傳送門 解析: 這道題可以把所有串接在一起構建字尾自動機來做,但是那樣還不如寫字尾陣列。。。 所以這裡提供一個只有字尾自動機能實現的做法。 思路: 首先構建出第一個串的字尾自動機。 然後拿其他的串放到字尾自動機上面跑。同時更新答案。 程式碼裡面的
Longest Common Substring II (字尾自動機)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor
Longest Common Substring II(字尾自動機)
題目描述 傳送門 題意:給出若干串,求最長公共子串。 題解 這明明就是一道sa的題嘛,可是為了練習sam用sam來寫 首先對於第一個串構建sam 對於每一個狀態s,記錄一下它對於每一個串
求兩個字串最長公共子串(動態規劃)
code如下: //Longest common sequence, dynamic programming method void FindLCS(char *str1, char *str2) { if(str1 == NULL || str2 == NULL)
《程式設計師程式碼面試指南》求兩個字串最長公共子串
/** * 題目: * 給定兩個字串 str1 和 str2,返回兩個字串的最長公共子串。 *舉例: * str1 = "1AB2345CD",str2 = "12345EF",返回"2345"。 */ /** * 解答: * 經典動態規劃的方法可以做到時間複
BZOJ 2946 POI2000 公共串 後綴自動機(多串最長公共子串)
調整 log spa size 暴力 pan emc auto 結束 題意概述:給出N個字符串,每個串的長度<=2000(霧。。。可能是當年的年代太久遠機子太差了),問這N個字符串的最長公共子串長度為多少。(N<=5) 拋開數據結構,先想想樸素做法。 設計一
如何求兩字串的最長公共子串
此演算法的時間複雜度我還沒想清楚, 程式碼如下: #include<stdio.h>#include<string.h> char * maxsamesubstring(char *s1,char *s2){ int i,j,len,maxlen,i
SPOJ 1812 Longest Common Substring II 字尾自動機求多字串最長公共子串
題意: 給若干字串,求它們的最長公共子串的長度。 題解:字尾自動機。 對第一個串建立SAM,並拓撲排序。 用後面的串分別匹配。 對於SAM,每個節點新增兩個值ml,ans; ml代表該節點滿足單一字串時的最大值,匹配完一個字串後重置為0; an
【SPOJ】Longest Common Substring II (後綴自動機)
公共子串 排序 -i max node bstr cst 後綴 post 【SPOJ】Longest Common Substring II (後綴自動機) 題面 Vjudge 題意:求若幹個串的最長公共子串 題解 對於某一個串構建\(SAM\) 每個串依次進行匹配 同時記
SPOJ 1811. Longest Common Substring (LCS,兩個字串的最長公共子串, 字尾自動機SAM)
/* *********************************************** Author :kuangbin Created Time :2013-9-8 23:27:46 File Name :F:\2013ACM練習\專
SPOJ LCS2 - Longest Common Substring II 後綴自動機 多個串的LCS
plus namespace sub align call 節點 inline cto res LCS2 - Longest Common Substring II no tags A string is finite sequence of cha
SPOJ 1812 LCS2 - Longest Common Substring II (後綴自動機)【兩種做法】
spoj name memset cstring pre fin cbi dcb 每次 手動博客搬家: 本文發表於20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人
[SPOJ] (1812) Longest Common Substring II ---- SAM(多個串的最長公共子串)
題目傳送門 做法: 類似求兩個串的最長公共子串。 我們對第一個串建立自動機,然後把剩餘的n-1個串放進自動機上匹配。 每個串都儲存它們在每個狀態上的匹配的最大長度ml, 然後對於每個狀態,維護一個數組
LCS2 Longest Common Substring II (求若干個串的最長公共子串模板題)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring,
常見演算法問題之最長公共子串問題(Longest common substring problem)
對於尋找兩個字串的最長公共子字串的問題,暴力搜尋的方式的時間複雜度將高達O(n^3), 而通過字尾樹的方式可將時間複雜度降低到O(n^2)。 以下是我實現的C++原始碼: #include <
最長公共子串(Longest Common Substring)
#include <iostream> using namespace std; int dp[30][30]; int maxlen; /* 記錄最大公共子串長度 */ int maxindex; /* 記錄最大公共子串在串1的起始位置 */ vo
LCS(longest common subsequence)(最長公共子序列)演算法(模板)
看了幾分寫的相當好的部落格: 下面內容來轉載自上面文章 問題描述 什麼是最長公共子序列呢?好比一個數列 S,如果分別是兩個或多個已知數列的子序列,且是所有符合此條件序列中最長的,則S 稱為已知序列的最長公共子序列。 舉個例子,如:有兩條
最長公共子串問題 Longest Common Substring LCST 動態規劃
* 題目: 給定2個字串$str1, $str2, 返回2個字串的最長公共子串 e.g. $str1 = "1AB2345CD"; $str2 = "12345EF" 返回: "2345" 要求: 如果$str1 長度為M, $str2長度為N, 實現時間複雜度為
最長公共子串(Longest Common SubStrings)
Description 給出兩個字串,求出兩個字串的公共子串? sample Input encodingmy mydecoding sample Output coding