2011-09-19 22 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); 
     } 
    } 
} 

我希望這有助於和對不起,如果我做了太多的工作適合你。
最好的學習方法在做,我同意。