2017/11/21
KMP字符串匹配的应用问题
KMP字符串匹配可参考上一篇博客。
问题描述:
给定两个二叉树T1和T2,返回T1的某个子树结构是否与T2的结构相等。
思路
常规思路是遍历二叉树,判断是否匹配,这里使用KMP字符串匹配的思想。
1、将二叉树结构匹配问题转换成字符串匹配问题。
2、二叉树转换成字符串。将二叉树每个节点的值后面都添加一个特殊符号作为划定值边界的符号,如“_”,空节点用另一个特殊符号表示,如“#”,两个二叉树就转换为两个字符串。
如:
3
/ \
2 1
/\
4 6
转换成字符串后为:“3_2_4_#_#_6_#_#_1_#_#_”
还要注意的是,转化字符串的顺序两颗树要保持一致,比如上述同为前序遍历。
3、然后将转换为字符串的两棵树用KMP字符串进行匹配即可。
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/*
2017/11/18
KMP扩展问题2:
给定两个二叉树T1和T2,返回T1的某个子树结构是否与T2的结构相等。
*/
#if 1
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL){}
};
string Tree2string(TreeNode *root)
{
if (root == NULL)
return "#_";
string str = to_string(root->val) + "_";
return str + Tree2string(root->left) + Tree2string(root->right);
}
vector<int> getnext(string s)
{
vector<int>next(s.length());
next[0] = -1;
if (s.length() < 2)
return next;
next[1] = 0;
int cn = 0;
int i = 2;
while (i < s.length())
{
if (s[i - 1] == s[cn])
next[i++] = ++cn;
else if (cn>0)
cn = next[cn];
else
next[i++] = 0;
}
return next;
}
int KMP(string s1, string s2)
{
if (s1.length() == 0 || s2.length() == 0 || s1.length() < s2.length())
return -1;
int i = 0;
int j = 0;
vector<int> next = getnext(s2);
while (i<s1.length() && j<s2.length())
{
if (s1[i] == s2[j])
{
i++;
j++;
}
else if (next[j] == -1)
i++;
else
j = next[j];
}
return j == s2.length() ? i - j : -1;
}
bool T2subTreeEqualT2(TreeNode *p1, TreeNode *q1)
{
string s1 = Tree2string(p1);
string s2 = Tree2string(q1);
return KMP(s1, s2) != -1;
}
void main()
{
TreeNode *p1 = new TreeNode(1);
TreeNode *p2 = new TreeNode(2);
TreeNode *p3 = new TreeNode(3);
TreeNode *p4 = new TreeNode(4);
TreeNode *p5 = new TreeNode(5);
p1->left = p2;
p1->right = p3;
p2->left = p4;
p2->right = p5;
p3->left = NULL;
p3->right = NULL;
p4->left = NULL;
p4->right = NULL;
p5->left = NULL;
p5->right = NULL;
TreeNode *q1 = new TreeNode(2);
TreeNode *q2 = new TreeNode(4);
TreeNode *q3 = new TreeNode(5);
q1->left = q2;
q1->right = q3;
q2->left = NULL;
q2->right = NULL;
q3->left = NULL;
q3->right = NULL;
cout << T2subTreeEqualT2(p1, q1) << endl;
system("pause");
}
#else
#endif