1. 程式人生 > >利用KMP演算法,求順序表儲存的兩個字串的最長公共子串

利用KMP演算法,求順序表儲存的兩個字串的最長公共子串

/*程式說明:
*   程式是由順序表實現,功能為查詢兩字串中的最長公共子串;
*   兩條字串分別由兩個順序表儲存;
*   查詢思路是分解出短的那條字串的全部連續子串(例如abc分解為abc,ab,a,bc,b,c),
*   再使用kmp演算法將該全部子串與長的那條字串進行匹配,找到最長的那條子串;

*   完成日期:2017.5.20
*   編譯環境:visual studio 2015
*/

#include<iostream>
using namespace std;
const int MaxNum = 100;
struct SeqString//順序表結構
{
    int
length;//長度 char c[MaxNum];//儲存資料 }; typedef struct SeqString* PSeqString; PSeqString creatString(); void find(PSeqString t, PSeqString p); int KMPmatch(PSeqString t, PSeqString p2, int* next); void makenext(PSeqString p, int* next); void display(PSeqString pstr); int main() { PSeqString p = new
SeqString; p = creatString(); PSeqString t = new SeqString; t = creatString(); find(p, t); cin.get(); cin.get();//暫停 } PSeqString creatString()//建立並初始化一條字串 { PSeqString pstr = new SeqString; cout << "輸入其中一個字串:\n"; cin >> pstr->c; pstr->length = strlen
(pstr->c); return pstr; } void find(PSeqString t, PSeqString p)//查詢公共子串 { PSeqString temp = new SeqString; if (t->length < p->length)//交換使得p串為更短的那個字串 { temp = t; t = p; p = temp; } int* next = new int[MaxNum];//next陣列 int len = 0, maxlen = 0, loc = 0;//len為子串長度,maxlen為匹配成功的最長子串長度,loc為開始匹配子串的首下標 PSeqString p2 = new SeqString; int i, k, l; //i,j,k都是是字串的下標 //利用迴圈取不同的i和len,以達到取p不同的子字串的目的 for (int i = 0; i < p->length; i++)//改變i,此處i是p字串的下標 { for (len = p->length - i; len > 0; len--)//改變len { p2->length = len; for (k = 0, l = i; k < len; k++, l++)//使得p2為即將進行匹配的子串 { p2->c[k] = p->c[l]; } makenext(p2, next);//獲取p2的next陣列 if (KMPmatch(t, p2, next) && len > maxlen)//子串匹配成功且len最大則儲存len與i { maxlen = len; loc = i; } } } p2->length = maxlen; for (k = 0, l = loc; k < maxlen; k++, l++)//使得p2為最長公共子串 { p2->c[k] = p->c[l]; } cout << "最長的公共子串為: "; display(p2); delete(p2); delete(temp); } int KMPmatch(PSeqString t, PSeqString p2, int* next)//kmp演算法字串匹配 { int i = 0, j = 0; while (i < p2->length&&j < t->length) { if (i == -1 || p2->c[i] == t->c[j]) { i++, j++; } else i = next[i]; } if (i >= p2->length) return 1; else return 0; } void makenext(PSeqString p, int* next)//kmp演算法求next陣列 { int i = 0, k = -1; next[0] = -1; while (i < p->length - 1) { while (k >= 0 && p->c[i] != p->c[k]) k = next[k]; i++, k++; if (p->c[i] == p->c[k]) next[i] = next[k]; else next[i] = k; } } void display(PSeqString pstr)//顯示pstr順序表中的資料 { for (int i = 0; i < pstr->length; i++) { cout << pstr->c[i]; } }

測試結果