문제

누군가 C#에서 트리 구조를 탐색하기 위해 재귀적 람다 식을 구현하는 방법을 보여줄 수 있습니까?

도움이 되었습니까?

해결책

좋아, 드디어 자유시간을 찾았어.
여기 있습니다:

class TreeNode
{
    public string Value { get; set;}
    public List<TreeNode> Nodes { get; set;}


    public TreeNode()
    {
        Nodes = new List<TreeNode>();
    }
}

Action<TreeNode> traverse = null;

traverse = (n) => { Console.WriteLine(n.Value); n.Nodes.ForEach(traverse);};

var root = new TreeNode { Value = "Root" };
root.Nodes.Add(new TreeNode { Value = "ChildA"} );
root.Nodes[0].Nodes.Add(new TreeNode { Value = "ChildA1" });
root.Nodes[0].Nodes.Add(new TreeNode { Value = "ChildA2" });
root.Nodes.Add(new TreeNode { Value = "ChildB"} );
root.Nodes[1].Nodes.Add(new TreeNode { Value = "ChildB1" });
root.Nodes[1].Nodes.Add(new TreeNode { Value = "ChildB2" });

traverse(root);

다른 팁

적절한 솔루션, 실제로 많은 함수형 프로그래밍 언어의 관용적 솔루션은 다음을 사용하는 것입니다. 고정 소수점 결합기.간단히 말해서:고정 소수점 결합자는 "재귀적인 익명 함수를 어떻게 정의합니까?"라는 질문에 답합니다.그러나 해결책은 너무나 간단해서 이를 설명하기 위해 전체 기사가 작성되었습니다.

간단하고 실용적인 대안은 C의 장난을 "시간을 거슬러 올라가는 것"입니다.정의 전 선언.다음을 시도해 보십시오(“계속” 함수).

Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);

매력처럼 작동합니다.

또는 클래스 객체에 대한 선주문 트리 탐색의 경우 TreeNode 구현하는 IEnumerable<TreeNode> 적절하게 자식을 검토하려면 다음을 수행하십시오.

Action<TreeNode, Action<TreeNode>> preorderTraverse = null;
preorderTraverse = (node, action) => {
    action(node);
    foreach (var child in node) preorderTraverse(child, action);
};

간단한 대안은 C와 C++의 익살스러운 방식으로 "시간을 거슬러 올라가는 것"입니다.정의 전 선언.다음을 시도해 보세요:

Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);

매력처럼 작동합니다.

예, 한 가지 주의 사항이 있지만 작동합니다.C#에는 변경 가능한 참조가 있습니다.따라서 실수로 다음과 같은 일을 하지 않도록 주의하세요.

Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);

// Make a new reference to the factorial function
Func<int, int> myFact = fact;

// Use the new reference to calculate the factorial of 4
myFact(4); // returns 24

// Modify the old reference
fact = x => x;

// Again, use the new reference to calculate
myFact(4); // returns 12

물론 이 예제는 약간 인위적이지만 가변 참조를 사용할 때 이런 일이 발생할 수 있습니다.다음의 결합자를 사용하는 경우 아쿠님의 링크로는 불가능합니다.

계층 구조를 나타내는 Children 컬렉션을 포함하는 신화적인 개체 TreeItem을 가정합니다.

    public void HandleTreeItems(Action<TreeItem> item, TreeItem parent)
    {
        if (parent.Children.Count > 0)
        {
            foreach (TreeItem ti in parent.Children)
            {
                HandleTreeItems(item, ti);
            }
        }

        item(parent);
    }

이제 이를 호출하고 항목 하나를 처리하는 람다를 콘솔에 출력하여 전달합니다.

HandleTreeItems(item => { Console.WriteLine(item.Name); }, TreeItemRoot);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top