用 C# 实现的前缀树 - Trie

拜读了 Jeffery Zhao 的大作 后,有自己写一棵前缀树的冲动,于是花了一点时间,朴素地实现了。

[EDIT]发现这个实现有很多漏洞,隐藏了……真要看,点此展开

代码:

using System.Collections.Generic;

namespace DataStructure.Trees
{
    public sealed class Trie<TKeyFragment, TValue>
    {
        private TrieNode<TKeyFragment, TValue> root;

        public Trie()
        {
            root = new TrieNode<TKeyFragment, TValue>();
        }

        public Trie( TrieNode<TKeyFragment, TValue> root )
        {
            this.root = root;
        }

        public bool Store( IEnumerable<TKeyFragment> key, TValue value )
        {
            return root.Expand(key.GetEnumerator(), value);
        }

        public IEnumerable<TValue> LookFor( IEnumerable<TKeyFragment> key )
        {
            return root.LookFor(key.GetEnumerator());
        }
    }

    public class TrieNode<TKeyFragment, TValue>
    {
        protected Dictionary<TKeyFragment, TrieNode<TKeyFragment, TValue>> Table = new Dictionary<TKeyFragment, TrieNode<TKeyFragment, TValue>>();

        protected List<TValue> ValueCollection = new List<TValue>();

        protected internal virtual bool Expand( IEnumerator<TKeyFragment> keyEnumerator, TValue value )
        {
            if ( keyEnumerator.MoveNext() )
            {
                var nextfragment = keyEnumerator.Current;
                if ( !Table.ContainsKey(nextfragment) )
                {
                    Table.Add(nextfragment, new TrieNode<TKeyFragment, TValue>());
                }
                return Table[nextfragment].Expand(keyEnumerator, value);
            }
            else
            {
                if ( !this.ValueCollection.Contains(value) )
                {
                    this.ValueCollection.Add(value);
                }
                return true;
            }
        }

        protected internal virtual IEnumerable<TValue> LookFor( IEnumerator<TKeyFragment> keyEnumerator )
        {
            if ( keyEnumerator.MoveNext() )
            {
                var nextfragment = keyEnumerator.Current;
                if ( !Table.ContainsKey(nextfragment) )
                {
                    return new List<TValue>();
                }
                return Table[nextfragment].LookFor(keyEnumerator);
            }
            else
            {
                return ValueCollection;
            }
        }
    }
}

用的话键的类型要实现 IEnumerable<TKeyFragment>,用法简单:

class Program
{
    static void Main( string[] args )
    {
        var mytrie = new Trie<char, string>();

        mytrie.Store("I Love You", "Guys");
        mytrie.Store("I Love You", "Cnblogs");
        mytrie.Store("I Hate You", "Bad Guy");
        mytrie.Store("I Hate You", "WTF");

        mytrie.LookFor("I Love You").ToList().ForEach(str => Console.WriteLine(str));
        mytrie.LookFor("I Hate You").ToList().ForEach(str => Console.WriteLine(str));
    }
}

还没有想到怎么合并没有对应 Value 的中间节点,回去再想想。

转载于:https://www.cnblogs.com/Diryboy/archive/2009/03/18/CSharpTrie.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值