Programing

C #에서 트리를 순회하는 재귀 람다 식

lottogame 2020. 11. 21. 08:20
반응형

C #에서 트리를 순회하는 재귀 람다 식


누군가 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

물론이 예제는 약간 인위적이지만 가변 참조를 사용할 때 발생할 수 있습니다. aku 의 링크 에서 결합 자를 사용하면 가능하지 않습니다.


계층을 나타내는 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);

참고URL : https://stackoverflow.com/questions/61143/recursive-lambda-expression-to-traverse-a-tree-in-c-sharp

반응형