zoukankan      html  css  js  c++  java
  • 遇到的一道算法题

    题目是给定一个字符串, 该字符串是一种简单的类似于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;
            }
  • 相关阅读:
    leetcode 155. Min Stack 、232. Implement Queue using Stacks 、225. Implement Stack using Queues
    leetcode 557. Reverse Words in a String III 、151. Reverse Words in a String
    leetcode 153. Find Minimum in Rotated Sorted Array 、154. Find Minimum in Rotated Sorted Array II 、33. Search in Rotated Sorted Array 、81. Search in Rotated Sorted Array II 、704. Binary Search
    leetcode 344. Reverse String 、541. Reverse String II 、796. Rotate String
    leetcode 162. Find Peak Element
    leetcode 88. Merge Sorted Array
    leetcode 74. Search a 2D Matrix 、240. Search a 2D Matrix II
    Android的API版本和名称对应关系
    spring 定时任务执行两次解决办法
    解析字符串为泛型的方法
  • 原文地址:https://www.cnblogs.com/VectorZhang/p/5365491.html
Copyright © 2011-2022 走看看