后缀树 最长公共子串

1. 代码如下:

#include <iostream> #include <string> #include <set> using namespace std; const int TREE_WIDTH = 256; const int WORDLENMAX = 128; // for the longest common substring problem // WHITE means dont contain neither 1 or 2 // RED means contain 1 $ // BLUE means contain 2 # // BLACK means contain both enum COLOR { WHITE = 0, RED = 1, BLUE = 2, BLACK = 3 }; class TrieNode { public: COLOR color; TrieNode *parent; TrieNode *next[TREE_WIDTH]; TrieNode(TrieNode* p = NULL, COLOR c = WHITE) : parent(p), color(c) { for (int i = 0; i < TREE_WIDTH; i++) { next[i] = NULL; } } }; class Trie { public: Trie() { root = new TrieNode(); } int insert(const char* word); void longestCommonSubstring() { longestCommonSubstring(root); } private: void travel(TrieNode *p); void longestCommonSubstring(TrieNode *p); TrieNode* root; }; int Trie::insert(const char *word) { int i; TrieNode *curr, *newnode; if (word[0] == '/0') { return 0; } string s(word); COLOR c = WHITE; switch(s[s.size()-1]) { case '$': c = RED; break; case '#': c = BLUE; break; default: break; } //cout << "inserting " << s << " with color " << c << endl; curr = root; curr->color = (COLOR)(curr->color | c); for (i = 0;; ++i) { if (curr->next[ word[i] ] == NULL) { newnode = new TrieNode(curr); curr->next[ word[i] ] = newnode; } if (word[i] == '/0') { break; } curr->color = (COLOR)(curr->color | c); curr = curr->next[ word[i] ]; } return 0; } bool myfn(string i, string j) { return i.size() < j.size(); } static set<string> s; void Trie::longestCommonSubstring(TrieNode* p) { travel(p); cout << *max_element(s.begin(), s.end(), myfn) << endl; } void addWord(const char *str) { s.insert(string(str)); } void Trie::travel(TrieNode *p) { static char worddump[WORDLENMAX+1]; static int pos=0; int i; if (p == NULL) { return; } if (p->color != BLACK) { worddump[pos - 1]='/0'; addWord(worddump); } if(p->color == BLACK) { for (i=0; i<TREE_WIDTH; ++i) { worddump[pos++]=i; travel(p->next[i]); pos--; } } return; } int main(void) { Trie trie; string s1, s2; cin >> s1; cin >> s2; cout << "finding the longest common substring of " << s1 << " and " << s2 << " :"<< endl; s1 = s1 + "#"; s2 = s2 + "$"; for (unsigned int i = 0; i < s1.size(); i++) { trie.insert(s1.substr(i).c_str()); } for (unsigned int i = 0; i < s2.size(); i++) { trie.insert(s2.substr(i).c_str()); } trie.longestCommonSubstring(); return 0; }

2. 运行结果如下:

/home/a/j/nomad2:cat input|./a.out finding the longest common substring of dababced and bababcff : ababc

3. 说明: 在建完后缀树后,对所有节点做标记,然后寻找深度最深的同时含有(#和$)的节点,复杂度为O(m+n).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值