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;
            }
  • 相关阅读:
    1.4.2.3. SETUP(Core Data 应用程序实践指南)
    1.4.2.2. PATHS(Core Data 应用程序实践指南)
    1.4.2.1. FILES(Core Data 应用程序实践指南)
    1.4.2. 实现 Core Data Helper 类(Core Data 应用程序实践指南)
    1.4.1. Core Data Helper 简介(Core Data 应用程序实践指南)
    1.4. 为现有的应用程序添加 Core Data 支持(Core Data 应用程序实践指南)
    1.3.2. App Icon 和 Launch Image(Core Data 应用程序实践指南)
    1.3.1. 新建Xcode项目并设置故事板(Core Data 应用程序实践指南)
    php验证邮箱是否合法
    如何使js函数异步执行
  • 原文地址:https://www.cnblogs.com/VectorZhang/p/5365491.html
Copyright © 2011-2022 走看看