Пример #1
0
        public void TrieConstructorTest()
        {
            Trie <TrieElement> trie = new Trie <TrieElement>();

            Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("VLUnitTests.Resources.TrieTest.txt");
            string text   = stream.ReadAll(); // read all data from testing file

            // add "references" that will be searched
            trie.Add("id.aliquam.lorem");
            trie.Add("a.b.c.d");
            trie.Add("x.y");
            trie.Add("eeee.eeee");

            // complete building the trie
            trie.CreatePredecessorsAndShortcuts();

            TrieElement   e          = trie.Root;
            List <string> foundWords = new List <string>();

            // create list of expeced results
            List <string> expectedWords = new List <string>();

            expectedWords.Add("id.aliquam.lorem");
            expectedWords.Add("id.aliquam.lorem");
            expectedWords.Add("eeee.eeee");
            expectedWords.Add("id.aliquam.lorem");
            expectedWords.Add("eeee.eeee");
            expectedWords.Add("eeee.eeee");
            expectedWords.Add("eeee.eeee");
            expectedWords.Add("a.b.c.d");
            expectedWords.Add("a.b.c.d");
            expectedWords.Add("a.b.c.d");
            expectedWords.Add("a.b.c.d");
            expectedWords.Add("a.b.c.d");

            // run the algorithm
            foreach (char c in text)
            {
                e = trie.Step(e, c);
                if (e.IsTerminal)
                {
                    foundWords.Add(e.Word);
                }
            }

            // compare with expected
            if (foundWords.Count == expectedWords.Count)
            {
                bool ok = true;
                for (int i = 0; i < foundWords.Count; i++)
                {
                    ok = ok && foundWords[i] == expectedWords[i];
                }
                Assert.IsTrue(ok);
            }
            else
            {
                Assert.Fail("Found and expected words count don't match.");
            }
        }
Пример #2
0
        private void Add(IList <T> key, IEnumerable <T> fullkey)
        {
            if (!key.Any())
            {
                _children[new T[0]] = new TrieElement(fullkey, _comp);
                return;
            }
            bool included;
            var  match = _children.FirstOrDefault(a => a.Key.StartsWith(key, _tokencomp), out included);

            if (included)
            {
                if (match.Key.CompareCount(key) != 0)
                {
                    //we need to split an existing key
                    _children.Remove(match.Key);
                    var newchild = new Trie <T>(_comp, _tokencomp)
                    {
                        { new T[0], fullkey }
                    };
                    newchild._children[match.Key.Slice(key.Count)] = match.Value;
                    _children[key] = newchild;
                    return;
                }
                // we add epsilon value
                var trie = match.Value as Trie <T>;
                trie?.Add(new T[0], fullkey);
                return;
            }
            match = _children.FirstOrDefault(a => a.Key.Any() && key.StartsWith(a.Key, _tokencomp), out included);
            if (included)
            {
                //we need to split this key
                var trie = match.Value as Trie <T>;
                if (trie == null)
                {
                    _children.Remove(match);
                    trie = new Trie <T>(_comp, _tokencomp)
                    {
                        { new T[0], match.Value.First() }
                    };
                    _children[match.Key] = trie;
                }
                trie.Add(key.Slice(match.Key.Count), fullkey);
                return;
            }
            var submatch = _children.Attach(a => a.Key.LongestCommonPrefix(key, _tokencomp)).FirstOrDefault(a => a.Item2.Any(), out included);

            if (included)
            {
                //we need to split both
                match = submatch.Item1;
                var prefix = submatch.Item2.Select(a => a.Item1).ToArray();
                _children.Remove(match.Key);
                var newchild = new Trie <T>(_comp, _tokencomp)
                {
                    { key.Slice(prefix.Length), fullkey }
                };
                newchild._children[match.Key.Slice(prefix.Length)] = match.Value;
                _children[prefix] = newchild;
                return;
            }
            //we have no definitions for anything like this key
            this._children[key] = new TrieElement(fullkey, _comp);
        }