2011-09-19 1 views
1

저는 C# 초보자이며 지금은 다른 문제로 스스로에게 도전하려고합니다.하나 이상의 루프와 "깨끗한"코드를 사용하여 여러 수준의 여러 고유 한 자식 추가

현재 문자 및 와일드 카드를 입력하여 가능한 단어를 검색 할 수있는 웹 응용 프로그램을 구축하려고합니다.

이 질문에 대한 이전 질문 내가 400k + 단어에서 생성 된 편지를 포함하는 Trie를 작성하기로 결정했습니다. 나중에 Trie에서 문자 및 와일드 카드 입력에 따라 가능한 단어 일치 항목을 검색합니다.

저는 두 개의 클래스를 만들었습니다. 하나는 Trie에 하나의 노드를 나타내고 다른 하나는 Trie를 나타냅니다.

저는 현재 정지 상태에 있습니다. 제 문제는 여러 레벨의 Trie에 여러 명의 자녀를 추가하고 모든 어린이가 uniqe이어야한다는 것입니다.

수동과 같이 보일 것이다 이렇게 :

//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 1, Question 2.

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

Btw, 당신은 다른 값을 사용하는 논리가 없기 때문에 짧은 버전을 사용하는 것이 좋습니다. public char Letter {get; 세트; }','public bool IsEndOfWord {get; 세트; }','public List 아이들 {get; 세트; }'. – ANeves

+0

@ANeves 오, 알겠습니다, 감사합니다. –

답변

1

그러나 나는 내 재귀 방법은 TrieNode 클래스 안에 것뿐만 아니라 재귀를 통해이 작업을 수행 할 것 :

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

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; 
    } 
} 

마지막으로 당신은 당신의 트리는 생성자에서 초기 루프를 변경해야

(참고 : 오타가있을 수 있으므로이 코드를 테스트하지 않았습니다.)

2

당신이 재귀 찾고 계십니까 : 내 트리는 클래스 여기

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; 
    } 
} 

... 그리고 :

여기 내 TrieNode 클래스입니까?
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); 
     } 
    } 
} 

은 내가 당신을 위해 너무 많은 일을 한 경우에이 도움이, 미안 바랍니다.
을 배우는 가장 좋은 방법은입니다.

관련 문제