Trie樹-髒詞過濾應用

Trie樹,又稱字符查找樹、前綴樹,主要用於字符匹配(詳見http://en.wikipedia.org/wiki/Trie)。適合做關鍵詞查找,比如查找文章中的關鍵字然後給他們加鏈接。 當然對髒詞的過濾應用也是樣,只是把替換連接的工作換成了替換字符。

當前的代碼還只是進行簡單的替換,並沒有做一些字符的處理,比如“昨天見到你媽,逼我要買房”,這本身不是髒詞,因爲有逗號,所以程序裏要增加字符的範圍判斷。

程序中的skip就是用來過濾髒詞的簡單變體,比如“找*小*姐”,默認是最多跳過3個字符,這個可以隨便調整了。總之是一個Trie的鍛鍊吧。


    public class TrieTree
    {
        private readonly Dictionary<char, TrieTree> Children;

        public bool End { get; set; }

        public TrieTree()
        {
            Children = new Dictionary<char, TrieTree>();
        }

        public void AddKey(string keyword)
        {
            if (String.IsNullOrEmpty(keyword))
            {
                return;
            }

            var cNode = this;

            foreach (var key in keyword)
            {
                if (cNode.Children.ContainsKey(key))
                {
                    cNode = cNode.Children[key];
                }
                else
                {
                    var node = new TrieTree();
                    cNode.Children.Add(key, node);
                    cNode = node;
                }
            }
            cNode.End = true;
        }


        public void Replace(ref string text)
        {
            for (var i = 0; i < text.Length; i++)
            {
                var cNode = this;
                var key = text[i];
                //碰到髒詞的第一個詞
                if (cNode.Children.ContainsKey(key))
                {
                    cNode = cNode.Children[key];
                    //查找是否包含髒詞後面的詞
                    var skip = 0;
                    for (var j = i + 1; j < text.Length; j++)
                    {
                        if (cNode.Children.ContainsKey(text[j]))
                        {
                            cNode = cNode.Children[text[j]];
                            skip = 0;
                        }
                        else
                        {
                            //允許略過過幾個字符
                            skip++;
                            if (skip > 3)
                            {
                                break;
                            }
                        }
                        if (cNode.End)
                        {
                            var len = j + 1 - i;
                            text = text.Replace(text.Substring(i, len), string.Empty.PadLeft(len, '*'));
                            i += len;
                            break;
                        }
                    }
                }
            }
        }

    }

使用方法如下:

    class Program
    {
        static void Main(string[] args)
        {
            var trie = new TrieTree();
            var keywords = "我操,妓女,fuck".Split(',');
            foreach (var key in keywords)
            {
                trie.AddKey(key);
            }

            var text = @"我擦啊,尼瑪,我操你媽,fuck you,你這個妓女,賤人。";
            trie.Replace(ref text);
            Console.WriteLine(text);
            Console.Read();
        }
    }

執行的結果:


發佈了42 篇原創文章 · 獲贊 191 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章