遇到的一道算法题

题目是给定一个字符串, 该字符串是一种简单的类似于Javascript函数调用。

比如 func1(123, 456) 或者 func1(123, 456, func2(78, 'abc'))

要求输出是该字符串的一个解析树。

func1(123, 456)  输出为

func1(123, 456) 
    |
    ---------123
    |
    ---------456

func1(123, 456, func2(78, 'abc')) 输出为

func1(123, 456, func2(78, 'abc'))
        |
        -----------------------------123
        |
        ----------------------------456
        |
        ----------------------------func2(78, 'abc')
                      |
                      --------------78
                      |
                      --------------'abc'

为了简化题目,假设函数调用肯定是合法的,即函数左右括号肯定匹配,函数参数若是字符串都包括在单引号内,单引号内不存在括号、不存在逗号等等

这里直接给出了一个C#实现。如果有错误或者有更好的算法 请各位支出。

        public class TreeNode
        {
            public string Function { get; set; }
            public List<object> Parameters { get; set; }

            public void Print(int emptyCount = 0)
            {
                var length = emptyCount + Function.Length;
                System.Console.WriteLine(new string(' ', emptyCount) + Function);

                if (Parameters != null)
                {
                    foreach (var parameter in Parameters)
                    {
                        if (parameter is TreeNode)
                        {
                            (parameter as TreeNode).Print(length);
                        }
                        else
                        {
                            System.Console.WriteLine(new string(' ', length) + parameter);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// "func1(12, 'abc')" => ["12", "'abc'"]
        /// "func1(12, 'abc', func2(34, 56))" => ["12", "'abc'", "func2(34, 56)"]
        /// </summary>
        public static List<string> ParseFunction(string str)
        {
            if (string.IsNullOrEmpty(str))
                throw new ArgumentNullException("str");

            int leftBracketIndex = str.IndexOf("(", StringComparison.OrdinalIgnoreCase);
            int rightBracketIndex = str.LastIndexOf(")", StringComparison.OrdinalIgnoreCase);

            if (leftBracketIndex < 0 || rightBracketIndex < 0)
                throw new ArgumentException(str + " is not a function call.");

            string value = str.Substring(leftBracketIndex + 1, rightBracketIndex - leftBracketIndex - 1).Trim();

            List<string> result = new List<string>();
            string tmp = "";
            int bracketCount = 0;
            foreach (char c in value)
            {
                if (c == '(')
                {
                    bracketCount++;
                    tmp += c;
                }
                else if (c == ')')
                {
                    bracketCount--;
                    tmp += c;
                }
                else if (c == ',')
                {
                    if (bracketCount == 0)
                    {
                        result.Add(tmp.Trim());
                        tmp = "";
                    }
                    else
                    {
                        tmp += c;
                    }
                }
                else
                {
                    tmp += c;
                }
            }

            if (tmp != "")
            {
                result.Add(tmp.Trim());
            }

            return result;
        }

        public static bool IsFunctionCall(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return false;
            }

            if (str.Trim().First() == '\'' && str.Trim().Last() == '\'')
            {
                return false;
            }

            int leftBracketIndex = str.IndexOf("(", StringComparison.OrdinalIgnoreCase);
            int rightBracketIndex = str.LastIndexOf(")", StringComparison.OrdinalIgnoreCase);

            if (leftBracketIndex < 0 && rightBracketIndex < 0)
            {
                return false;
            }

            return true;
        }

        public static TreeNode ParseFunctionCall(string str)
        {
            TreeNode node = new TreeNode() {Function = str};
            node.Parameters = new List<object>();
            foreach (var param in ParseFunction(str))
            {
                if (IsFunctionCall(param))
                {
                    node.Parameters.Add(ParseFunctionCall(param));
                }
                else if(!string.IsNullOrEmpty(param))
                {
                    node.Parameters.Add(param);
                }
            }

            return node;
        }
原文地址:https://www.cnblogs.com/VectorZhang/p/5365491.html