已回答  将C#递归方法转换为迭代方法

je79

新成员
已加入
2021年2月11日
留言内容
1
编程经验
10+
我有一个解析器的方法看起来像这样:
C#:
public List<SequenceTokenTableState> BuildSequenceTokenTableRecursive(string sequenceName = "", int level = 0, List<string> breadCrumbs = null, bool skipAddedEntries = true, bool printOnConsole = false)
{
    List<SequenceTokenTableState> list = new List<SequenceTokenTableState>();
    if (!string.IsNullOrEmpty(sequenceName))
    {
        var seq = new ParserSequence();
        if (SequencesDictionary.ContainsKey(sequenceName))
        {
            seq = SequencesDictionary[sequenceName];
        }
        else { return new List<SequenceTokenTableState>(); }
        for(int i=0;i<seq.Sections.Count;i++)
        {
            var sec = seq.Sections;
            if (sec.HasTokens || sec.HasDynamicRules) {
                if (sec.HasTokens)
                {
                    foreach(var token in sec.Tokens)
                    {
                        list.Add(new SequenceTokenTableState()
                                 {
                                     CallEnum = CallEnum.LexerCheckStart,
                                     Comments = InputLexer.RulesDictionary[token].RuleName + "/{" + InputLexer.RulesDictionary[token].StringToken + "} Opt:" + sec.IsOptional + " Rep:" + sec.IsRepeating,
                                     Level = level
                                     });
                    }
                }
                if (sec.HasDynamicRules)
                {
                    foreach(var rule in sec.DynamicRules)
                    {
                        list.Add(new SequenceTokenTableState()
                                 {
                                     CallEnum = CallEnum.LexerCheckStart,
                                     Comments = InputLexer.RulesDictionary[rule].RuleName + ":::Dynamic/{" + InputLexer.RulesDictionary[rule].StringToken + "} Opt:" + sec.IsOptional + " Rep:" + sec.IsRepeating,
                                     Level = level
                                     });
                    }
                }
            }
            if (sec.HasSequences)
            {
                for (int ii = 0; ii < sec.Sequences.Length; ii++)
                {
                    var seq1 = sec.Sequences[ii];
                    var rundata = BuildSequenceTokenTableRecursive(seq1, level + 1);
                    list.Add(new SequenceTokenTableState()
                             {
                                 CallEnum = CallEnum.GetMethodCallResult,
                                 Level = level,
                                 InnerStates = rundata,
                                 SequenceName = seq1,
                                 Comments = "Opt:" + sec.IsOptional + " Rep:" + sec.IsRepeating
                                 });
                }
            }
        }
        return list;
    }
    return new List<SequenceTokenTableState>();
}
它有点长,但是我要让您注意的主要事情是它在if,for,if和for循环中调用自身。该方法实质上是在进行预排序树遍历。

我想使用Stack将其转换为迭代方法,但不知道如何实现,特别是考虑到C#不允许您使用goto语句跳入循环,这很有意义。

如果您不知道,不用担心,只是打个招呼,我是这里的新成员!
 
由主持人最后编辑:

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
内联代码 按钮用于内联代码,即您在一行文本中包含的一小段代码,例如
I want to handle the Click event of a Button.
对于代码块,请使用 代码 按钮。从我对问题的编辑中可以看到,它提供的格式更加全面和可读。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,566
地点
悉尼,澳大利亚
编程经验
10+
对于这个问题,C#可以做什么并不是一开始就需要关注的事情,因为在考虑编写代码之前,您应该首先确定逻辑。无论您要完成的任务是什么,都应首先考虑如何手动执行,例如用笔和纸。然后,您可以优化算法的步骤并将其形式化。您可以对该算法进行多次手动测试,以确保其有效。一旦有了有效的算法,那么您就可以编写C#代码来专门实现它。这样,您总会有一些东西可以比较代码,以确保它确实按照预期的方式工作。您还可以进行调试,以准确确定实际行为可能与您期望的不同。如果您遇到问题,则可以向我们提供有关该问题的更加具体和相关的信息。而不是"我想做X,告诉我如何",您可以向我们确切说明您要尝试实现的内容以及如何实现,以及确切说明它在何处分解以及如何分解以及当时的实际输入和输出是什么。那是软件开发,而不是代码编写。
 
最佳 底部