#include <iostream>
#include <cstring>
using namespace std;
struct Edge
{
int l , r , len;
} edge [ 400000 ];
struct Node
{
Node * node [ 28 ];
Edge * edge [ 28 ];
bool info;
int activeLength;
Node * suffixLink;
Node * parent;
int num;
} node [ 400000 ], * st;
char strTemp [ 200008 ], pattern [ 200008 ];
class SuffixTree
{
public :
int nodeNum , edgeNum;
Node roots;
Node * activeNode;
Node * addNode;
int minDistance , lastBound;
int n;
char * str;
int maping [ 128 ];
SuffixTree()
{
nodeNum = edgeNum = minDistance = lastBound = 0;
memset( roots . node , NULL , sizeof( roots . node));
roots . info = false;
roots . suffixLink =& roots;
roots . activeLength = 0;
roots . num =- 1;
roots . parent = NULL;
activeNode =& roots;
addNode = NULL;
for( int i = 0; i < 128; i ++)
maping [ i ] = 26;
for( int i = 'a'; i <= 'z'; i ++)
maping [ i ] = i - 'a';
maping [ '#' ] = 27;
}
void create( char *s , int l)
{
str =s;
n = l;
Node * help;
for( int i = 0; i <n; i ++)
{
activeNode = activeNode -> suffixLink;
int start = i + activeNode -> activeLength;
int minDistanceTemp = lastBound - activeNode -> activeLength - i;
if( minDistanceTemp < 0)
minDistanceTemp = 0;
int t = maping [ str [ start ]];
while( activeNode -> node [ t ] != NULL &&
minDistanceTemp >= activeNode -> edge [ t ] -> len)
{
start = start + activeNode -> edge [ t ] -> len;
minDistanceTemp = minDistanceTemp - activeNode -> edge [ t ] -> len;
activeNode = activeNode -> node [ t ];
t = maping [ str [ start ]];
}
//沿边一个一个字符进行比较
help = activeNode;
bool flag = false;
int minDis = minDistanceTemp;
while( activeNode -> node [ t ] != NULL)
{
int record = maping [ str [ start ]];
start += minDis;
int l = help -> edge [ record ] -> l;
int r = help -> edge [ record ] -> r;
for( int j = l + minDis; j <= r; j ++ , start ++)
{
minDis = 0;
if( str [ j ] != str [ start ])
{
memset( node [ nodeNum ]. node , NULL , sizeof( node [ nodeNum ]. node));
node [ nodeNum ]. info = false;
node [ nodeNum ]. activeLength = activeNode -> activeLength + ( j - l);
node [ nodeNum ]. num = nodeNum;
flag = true;
help -> edge [ t ] -> r = j - 1;
help -> edge [ t ] -> len = j - help -> edge [ t ] -> l;
int tt = maping [ str [ j ]];
node [ nodeNum ]. edge [ tt ] =& edge [ edgeNum ];
edge [ edgeNum ]. l = j;
edge [ edgeNum ]. r = r;
edge [ edgeNum ]. len = r - j + 1;
node [ nodeNum ]. node [ tt ] = help -> node [ t ];
help -> node [ t ] -> parent =& node [ nodeNum ];
help -> node [ t ] =& node [ nodeNum ];
node [ nodeNum ]. parent = help;
help =& node [ nodeNum ];
++ edgeNum;
++ nodeNum;
goto ans;
}
}
activeNode = activeNode -> node [ t ];
help = activeNode;
t = maping [ str [ start ]];
}
ans:;
//增加新的信息节点
lastBound = start;
Node * stmp = help;
if( addNode != NULL)
{
while( stmp -> activeLength != addNode -> activeLength - 1)
stmp = stmp -> parent;
addNode -> suffixLink = stmp;
}
if( flag)
addNode = help;
else
addNode = NULL;
if( addNode != NULL && addNode -> activeLength == 1)
{
addNode -> suffixLink =& roots;
addNode = NULL;
}
t = maping [ str [ start ]];
memset( node [ nodeNum ]. node , NULL , sizeof( node [ nodeNum ]. node));
help -> node [ t ] =& node [ nodeNum ];
help -> edge [ t ] =& edge [ edgeNum ];
edge [ edgeNum ]. l = start;
edge [ edgeNum ]. r =n - 1;
edge [ edgeNum ]. len =n - start;
node [ nodeNum ]. info = true;
node [ nodeNum ]. num = nodeNum;
++ nodeNum;
++ edgeNum;
}
}
bool search( char * pattern)
{
int length = strlen( pattern ), patLen = 0;
Node * root =& roots;
while( true)
{
int temp = maping [ pattern [ patLen ++ ]];
if( root -> node [ temp ] == NULL)
return false;
if( patLen == length)
return true;
int l = root -> edge [ temp ] -> l + 1 , r = root -> edge [ temp ] -> r;
for( int i = l; i <= r; i ++)
{
if( str [ i ] != pattern [ patLen ++ ])
return false;
if( patLen == length)
return true;
}
root = root -> node [ temp ];
}
}
void dfs( Node * st , int l)
{
if( st -> info)
{
printf( " /n ");
return;
}
printf( "它的儿子节点如下: /n ");
l = l + 4;
for( int i = 0; i < 28; i ++)
{
if( st -> node [ i ])
{
for( int j = 0; j < l; j ++)
printf( " ");
printf( "%d " , st -> edge [ i ] -> l + 1);
for( int j = st -> edge [ i ] -> l; j <= st -> edge [ i ] -> r; j ++)
printf( "%c" , strTemp [ j ]);
dfs( st -> node [ i ], l + st -> edge [ i ] -> len);
}
}
}
~ SuffixTree()
{
nodeNum = edgeNum = minDistance = lastBound = 0;
memset( roots . node , NULL , sizeof( roots . node));
roots . info = false;
roots . suffixLink =& roots;
roots . activeLength = 0;
}
} suffixTree;
int main()
{
printf( "请输入字符串(只支持小写字母):");
scanf( "%s" , & strTemp);
int l = strlen( strTemp);
strTemp [ l ++ ] = '#';
strTemp [ l ] = '/0';
suffixTree . create( strTemp , l);
st =& suffixTree . roots;
suffixTree . dfs( st , 0);
printf( "请输入模式串(输入EOF结束):");
while( scanf( "%s" , & pattern) != EOF)
{
bool ret = suffixTree . search( pattern);
if( ret)
printf( "%s 是其子串 /n " , pattern);
else
printf( "%s 不是其子串 /n " , pattern);
printf( "请输入模式串(输入EOF结束):");
}
return 0;
}
#include <cstring>
using namespace std;
struct Edge
{
int l , r , len;
} edge [ 400000 ];
struct Node
{
Node * node [ 28 ];
Edge * edge [ 28 ];
bool info;
int activeLength;
Node * suffixLink;
Node * parent;
int num;
} node [ 400000 ], * st;
char strTemp [ 200008 ], pattern [ 200008 ];
class SuffixTree
{
public :
int nodeNum , edgeNum;
Node roots;
Node * activeNode;
Node * addNode;
int minDistance , lastBound;
int n;
char * str;
int maping [ 128 ];
SuffixTree()
{
nodeNum = edgeNum = minDistance = lastBound = 0;
memset( roots . node , NULL , sizeof( roots . node));
roots . info = false;
roots . suffixLink =& roots;
roots . activeLength = 0;
roots . num =- 1;
roots . parent = NULL;
activeNode =& roots;
addNode = NULL;
for( int i = 0; i < 128; i ++)
maping [ i ] = 26;
for( int i = 'a'; i <= 'z'; i ++)
maping [ i ] = i - 'a';
maping [ '#' ] = 27;
}
void create( char *s , int l)
{
str =s;
n = l;
Node * help;
for( int i = 0; i <n; i ++)
{
activeNode = activeNode -> suffixLink;
int start = i + activeNode -> activeLength;
int minDistanceTemp = lastBound - activeNode -> activeLength - i;
if( minDistanceTemp < 0)
minDistanceTemp = 0;
int t = maping [ str [ start ]];
while( activeNode -> node [ t ] != NULL &&
minDistanceTemp >= activeNode -> edge [ t ] -> len)
{
start = start + activeNode -> edge [ t ] -> len;
minDistanceTemp = minDistanceTemp - activeNode -> edge [ t ] -> len;
activeNode = activeNode -> node [ t ];
t = maping [ str [ start ]];
}
//沿边一个一个字符进行比较
help = activeNode;
bool flag = false;
int minDis = minDistanceTemp;
while( activeNode -> node [ t ] != NULL)
{
int record = maping [ str [ start ]];
start += minDis;
int l = help -> edge [ record ] -> l;
int r = help -> edge [ record ] -> r;
for( int j = l + minDis; j <= r; j ++ , start ++)
{
minDis = 0;
if( str [ j ] != str [ start ])
{
memset( node [ nodeNum ]. node , NULL , sizeof( node [ nodeNum ]. node));
node [ nodeNum ]. info = false;
node [ nodeNum ]. activeLength = activeNode -> activeLength + ( j - l);
node [ nodeNum ]. num = nodeNum;
flag = true;
help -> edge [ t ] -> r = j - 1;
help -> edge [ t ] -> len = j - help -> edge [ t ] -> l;
int tt = maping [ str [ j ]];
node [ nodeNum ]. edge [ tt ] =& edge [ edgeNum ];
edge [ edgeNum ]. l = j;
edge [ edgeNum ]. r = r;
edge [ edgeNum ]. len = r - j + 1;
node [ nodeNum ]. node [ tt ] = help -> node [ t ];
help -> node [ t ] -> parent =& node [ nodeNum ];
help -> node [ t ] =& node [ nodeNum ];
node [ nodeNum ]. parent = help;
help =& node [ nodeNum ];
++ edgeNum;
++ nodeNum;
goto ans;
}
}
activeNode = activeNode -> node [ t ];
help = activeNode;
t = maping [ str [ start ]];
}
ans:;
//增加新的信息节点
lastBound = start;
Node * stmp = help;
if( addNode != NULL)
{
while( stmp -> activeLength != addNode -> activeLength - 1)
stmp = stmp -> parent;
addNode -> suffixLink = stmp;
}
if( flag)
addNode = help;
else
addNode = NULL;
if( addNode != NULL && addNode -> activeLength == 1)
{
addNode -> suffixLink =& roots;
addNode = NULL;
}
t = maping [ str [ start ]];
memset( node [ nodeNum ]. node , NULL , sizeof( node [ nodeNum ]. node));
help -> node [ t ] =& node [ nodeNum ];
help -> edge [ t ] =& edge [ edgeNum ];
edge [ edgeNum ]. l = start;
edge [ edgeNum ]. r =n - 1;
edge [ edgeNum ]. len =n - start;
node [ nodeNum ]. info = true;
node [ nodeNum ]. num = nodeNum;
++ nodeNum;
++ edgeNum;
}
}
bool search( char * pattern)
{
int length = strlen( pattern ), patLen = 0;
Node * root =& roots;
while( true)
{
int temp = maping [ pattern [ patLen ++ ]];
if( root -> node [ temp ] == NULL)
return false;
if( patLen == length)
return true;
int l = root -> edge [ temp ] -> l + 1 , r = root -> edge [ temp ] -> r;
for( int i = l; i <= r; i ++)
{
if( str [ i ] != pattern [ patLen ++ ])
return false;
if( patLen == length)
return true;
}
root = root -> node [ temp ];
}
}
void dfs( Node * st , int l)
{
if( st -> info)
{
printf( " /n ");
return;
}
printf( "它的儿子节点如下: /n ");
l = l + 4;
for( int i = 0; i < 28; i ++)
{
if( st -> node [ i ])
{
for( int j = 0; j < l; j ++)
printf( " ");
printf( "%d " , st -> edge [ i ] -> l + 1);
for( int j = st -> edge [ i ] -> l; j <= st -> edge [ i ] -> r; j ++)
printf( "%c" , strTemp [ j ]);
dfs( st -> node [ i ], l + st -> edge [ i ] -> len);
}
}
}
~ SuffixTree()
{
nodeNum = edgeNum = minDistance = lastBound = 0;
memset( roots . node , NULL , sizeof( roots . node));
roots . info = false;
roots . suffixLink =& roots;
roots . activeLength = 0;
}
} suffixTree;
int main()
{
printf( "请输入字符串(只支持小写字母):");
scanf( "%s" , & strTemp);
int l = strlen( strTemp);
strTemp [ l ++ ] = '#';
strTemp [ l ] = '/0';
suffixTree . create( strTemp , l);
st =& suffixTree . roots;
suffixTree . dfs( st , 0);
printf( "请输入模式串(输入EOF结束):");
while( scanf( "%s" , & pattern) != EOF)
{
bool ret = suffixTree . search( pattern);
if( ret)
printf( "%s 是其子串 /n " , pattern);
else
printf( "%s 不是其子串 /n " , pattern);
printf( "请输入模式串(输入EOF结束):");
}
return 0;
}