2011-09-19 98 views
1

添加多个唯一的孩子我是C#初学者,此刻我试图用不同的问题来挑战自己。在多个层面与一个或多个循环和“干净”的代码

目前我正在试图建立一个Web应用程序,你可以输入字母和通配符后可能的单词进行搜索。

海槽这个以前的问题我已经决定要建立一个包含40万个,从字+字母生成一个特里。稍后,我将根据字母和通配符输入搜索Trie以查找可能的单词匹配。

我已经建立了两个类,在特里一个代表一个节点,一个代表全特里。

我目前处于停滞状态,我的问题是,我想多生几个孩子,多层次增加了特里和每个孩子必须是潮头。

这样做手工将是这个样子:

//Level 1 
Root.Children.Add(new TrieNode(Letter, false, new List<TrieNode>())); 
//Level 2 
Root.Children[0].Children.Add(new TrieNode(Letter, false, new List<TrieNode>())); 
//Level 3 
Root.Children[0].Children[0].Children.Add(new TrieNode(Letter, false, new List<TrieNode>())); 

问题是,我想与一个或多个环路增加孩子和做这种方式似乎有点“错误”:

LetterArray = Word.ToCharArray(); 
int level = 0; 
foreach (char Letter in LetterArray) 
{ 
    //Level 1 
    if (level == 0) 
     Root.Children.Add(new TrieNode(Letter, false, new List<TrieNode>())); 
    //Level 2 
    if (level == 1)  
     Root.Children[0].Children.Add(new TrieNode(Letter, false, new List<TrieNode>())); 
    //Level 3 
    if (level == 2) 
     Root.Children[0].Children[0].Children.Add(new TrieNode(Letter, false, new List<TrieNode>())); 

    level++; 
} 

我需要的是一个或多个具有“干净”代码的循环,认为你可以帮助我吗? 对于后来可以搜索到的Trie,我认为这些信件需要按顺序排列。 以下是我的其他相关问题:Question 1Question 2

这里是我的TrieNode类:

public class TrieNode 
{ 
    private char _Letter; 
    private bool _IsEndOfWord; 
    private List<TrieNode> _Children; 

    public char Letter { 
     get { return _Letter; } 
     set { _Letter = value; } 
    } 
    public bool IsEndOfWord { 
     get { return _IsEndOfWord; } 
     set { _IsEndOfWord = value; } 
    } 
    public List<TrieNode> Children { 
     get { return _Children; } 
     set { _Children = value; } 
    } 

    public TrieNode(char letter, bool isEndOfWord, List<TrieNode> children) { 
     Letter = letter; 
     IsEndOfWord = isEndOfWord; 
     Children = children; 
    } 
} 

...这是我的特里类:

public class Trie 
{ 
    private TrieNode _Root; 

    public TrieNode Root 
    { 
     get { return _Root; } 
     set { _Root = value; } 
    } 

    public Trie(List<string> Words) 
    { 
     Root = new TrieNode('^', false, new List<TrieNode>()); 
     char[] LetterArray; 

     foreach (String Word in Words) 
     { 
      LetterArray = Word.ToCharArray(); 

      foreach (char Letter in LetterArray) 
      { 
       // Here is where I want to add nodes to my Trie 
      } 
     } 
    } 
} 
+1

顺便说一句,因为你使用后备值没有其他逻辑,我建议你使用的短版:'公共字符字母{获得;组; }','public bool IsEndOfWord {get;组; }','公开名单孩子{get;组; }'。 – ANeves

+0

@ANeves哦,我明白了,非常感谢那个输入:D –

回答

1

我想通过递归做到这一点为好,但我的递归方法将是TrieNode类中:

public AddWord(string word) 
{ 
    if (String.IsNullOrEmpty(word)) 
    { 
     throw new ArgumentException("word must contain values.", word); 
    } 

    var letter = word[0]; 
    var child = Children.FirstOrDefault(x => x.Letter = letter); 

    if (child == null) 
    { 
     //The child doesn't exist. Create it. 
     child = new TrieNode(letter, false, new List<TrieNode>()); 
    } 

    if (word.Length > 1) 
    { 
     child.AddWord(word.Substring(1); 
    } 
    else 
    { 
     child.IsEndOfWord = true; 
    } 
} 

最后,你只需要改变你的初始循环在你的特里构造:

foreach (String Word in Words) 
{ 
    _Root.AddWord(Word); 
} 

(注意:我没有测试过这个代码,所以可能会出现拼写错误)。

2

您是否在寻找递归?
http://en.wikipedia.org/wiki/Recursion_%28computer_science%29

using System.Linq; 

public Trie(List<string> words) 
{ 
    Root = new TrieNode('^', false, new List<TrieNode>()); 
    // Might have gotten the wrong method, check with intellisense 
    char[] letters = words.SelectMany(word => word.ToCharArray()); 
    RecursiveAdd(letters, Root, 0); 
} 

private const int desiredDepth = 5; 
private void RecursiveAdd(char[] letters, TrieNode branch, currentDepth) 
{ 
    foreach(char letter in letters) { 
     TrieNode node = new TrieNode(Letter, false, new List<TrieNode>()); 
     branch.Children.Add(node); 
     if(currentDepth < desiredDepth) { 
      RecursiveAdd(letters, node, currentDepth+1); 
     } 
    } 
} 

我希望这有助于和对不起,如果我做了太多的工作适合你。
最好的学习方法在做,我同意。