• 遇到的一道算法题


    题目是给定一个字符串, 该字符串是一种简单的类似于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;
            }
  • 相关阅读:
    zigbee芯片
    笔记本ubuntu安装wifi驱动(未完成)
    我错了的N个学习
    《华为工作法》读书笔记
    bbblack的网络socket通信实验
    NB-IOT连接移动onenet平台流程
    移动onenet基础通信套件V1.08版本的AT指令测试
    CC3200使用MQTT的SSL加密证书可用日期修改
    利尔达NB-IOT模块烧写固件的步骤
    树莓派相机
  • 原文地址:https://www.cnblogs.com/VectorZhang/p/5365491.html
Copyright © 2020-2023  润新知