using System;
using System.Collections.Generic;
using System.Text;
public class ACAutoMachine
{
protected WordNode m_root;
public ACAutoMachine()
{
m_root = new WordNode();
m_root.layer = 0;
}
public void addWord(string v_dirtyWorld, string v_replaceWorld)
{
WordNode p = m_root;
for (int i = 0; i < v_dirtyWorld.Length; i++)
{
char c = v_dirtyWorld[i];
if (!p.data.ContainsKey(c))
p.data[c] = new WordNode(i + 1);
p = p.data[c];
}
p.replaceWorld = v_replaceWorld;
}
public void genFail()
{
Queue<WordNode> q = new Queue<WordNode>();
q.Enqueue(m_root);
while (q.Count > 0)
{
WordNode node = q.Dequeue();
foreach (KeyValuePair<char, WordNode> child in node.data)
{
WordNode fp = node.fail;
while (fp != null && !fp.data.ContainsKey(child.Key))
fp = fp.fail;
if (fp != null)
child.Value.fail = fp.data[child.Key];
else
child.Value.fail = m_root;
child.Value.failCharOutputNum = child.Value.layer - child.Value.fail.layer;
q.Enqueue(child.Value);
}
}
m_root.fail = m_root;
}
public string harmonize(string v_str)
{
StringBuilder sb = new StringBuilder();
int optIdx = 0;
WordNode curNode = m_root;
for (int i = 0; i < v_str.Length; i++)
{
char curC = v_str[i];
if (curNode.data.ContainsKey(curC))//匹配
{
curNode = curNode.data[curC];
if (curNode.replaceWorld != null)//之前匹配的字符串是敏感串
{
sb.Append(curNode.replaceWorld);//加入替换的字符串
optIdx += curNode.layer;//输出指针右移动
curNode = m_root;
}
}
else//失配
{
while(curNode!=m_root)
{
for (int j = 0; j < curNode.failCharOutputNum; j++)
sb.Append(v_str[optIdx++]);
curNode = curNode.fail;
if (curNode.data.ContainsKey(curC))
{
curNode = curNode.data[curC];
break;
}
}
if(curNode == m_root)
sb.Append(v_str[optIdx++]);
}
}
while (optIdx< v_str.Length)
sb.Append(v_str[optIdx++]);
return sb.ToString();
}
}
public class WordNode
{
public Dictionary<char, WordNode> data;
public string replaceWorld;
public WordNode fail;
public int layer;
public int failCharOutputNum;
public WordNode(int v_layer = 0)
{
data = new Dictionary<char, WordNode>();
replaceWorld = null;
fail = null;
layer = v_layer;
failCharOutputNum = 0;
}
}