<span style="font-size:18px;">后缀树--包含字符串所有后缀的压缩的字典树,<span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">给定一长度为n的字符串S=S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">1</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">2</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">..S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">i</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">..S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">n</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">,和整数i,1 <= i <= n,子串S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">i</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">i+1</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">...S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">n</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">都是字符串S的后缀。以字符串S=XMADAMYX为例,它的长度为8,所以S[1..8], S[2..8], ... , S[8..8]都算S的后缀,我们一般还把空字串也算成后缀。这样,我们一共有如下后缀。对于后缀S[i..n],我们说这项后缀起始于i。</span></span><ol style="margin: 0px; padding: 0px 0px 0px 40px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);"><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[1..8], XMADAMYX, 也就是字符串本身,起始位置为1</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[2..8], MADAMYX,起始位置为2</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[3..8], ADAMYX,起始位置为3</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[4..8], DAMYX,起始位置为4</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[5..8], AMYX,起始位置为5</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[6..8], MYX,起始位置为6</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[7..8], YX,起始位置为7</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[8..8], X,起始位置为8</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">空字串。记为$。</li></ol>
<span style="font-size:18px;">后缀树的应用</span>
<span style="font-size:18px;">后缀树的应用包括:查询主串是否包含子串,找出两字符串的最长公共子串,找出主串的最长回文字串,找出主串中的最长重复子串等等</span>
// ConsoleApplication17.cpp : 定义控制台应用程序的入口点。
//后缀数组--用于匹配子串
#include "stdafx.h"
#include<string>
#include<iostream>
#include<map>
#include<vector>
using namespace std;
struct SuffixTreeNode{
map<char, SuffixTreeNode*> children;
char value;
vector<int> indexes;//
void InsertString(string s1, int index){
if (s1.length() > 0){
char s = s1[0];
SuffixTreeNode *child = NULL;
if (children.find(s) != children.end()){
child = children[s];
}
else{
SuffixTreeNode* newNode=new SuffixTreeNode;
child = newNode;
child->value = s;
children[s] = child;
}
string remain = s1.substr(1);
child->indexes.push_back(index);
child->InsertString(remain, index);
}
}
vector<int> Get_index(string s1){
char s = s1[0];
if (s1.length() == 0)
return indexes;
else{
if (children.find(s) != children.end()){
string str = s1.substr(1);
SuffixTreeNode *child = children[s];
return child->Get_index(str);
}
else{
vector<int> empty;
return empty;
}
}
}
~SuffixTreeNode(){
map<char, SuffixTreeNode*>::iterator iter;
for (iter = children.begin(); iter != children.end(); iter++){
delete iter->second;
}
}
};
class SuffixTree{
public:
SuffixTreeNode* root;
SuffixTree(string s){
root = new SuffixTreeNode;
for (int i = 0; i < s.length(); i++){
string str = s.substr(i);
root->InsertString(str, i);
}
};
vector<int> getindex(string s){
return root->Get_index(s);
}
~SuffixTree(){
if (root != NULL){
delete root;
}
}
void printSuffixTree(SuffixTreeNode* root){
if (root)
{
cout << root->value << " ";
map<char, SuffixTreeNode*>::iterator iter;
for (iter = root->children.begin(); iter != root->children.end(); iter++){
//cout << endl;
printSuffixTree((iter)->second);
}
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
string testString = "mississippi";
string stringList[] = { "is", "sip", "hi", "sis" };
SuffixTree stree(testString);
stree.printSuffixTree(stree.root);
for (int i = 0; i < 4; i++){
vector<int> li = stree.getindex(stringList[i]);
if (li.size() != 0){
cout << stringList[i].c_str() << " ";
for (int j = 0; j < li.size(); j++){
cout << li[j] << " ";
}
cout << endl;
}
}
system("pause");
return 0;
}
<img src="https://img-blog.csdn.net/20160830150232203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />