【问题标题】:C# separate parent from child. (string search)C# 将父母与孩子分开。 (字符串搜索)
【发布时间】:2013-11-21 17:53:45
【问题描述】:

我是 C# 新手,没有大量选项来执行特定任务。但仍然面临创建科学计算器的挑战。

我想要得到的是分离父母,从孩子开始和结束标签。还要计算有多少个父级,以及哪个父级是第一个,然后是第二个,依此类推。

与每个孩子的内容。之后,我计算每个孩子的结果(如果有的话)并创建也被计算的父母的内容。

例如:

string somestring = "5+5+(3+1+(0+1))+5+5+(3+1+(0+1))";

从计算结果(示例在 javascript 中,但我想要在 C# 中):

result = 
[{
    "parent" : "content of parent",
    "child" : ["content of child","content of child"]
},
{
    "parent" : "content of parent",
    "child" :["content of child","content of child","content of child"]
}];

这样我可以:

  • 计算“结果”数组的长度以获取父母的数量。
  • 计算“子”数组的长度以获取子数。
  • 通过指向数组索引号获取元素的内容。

它不必在这种类型的数组中,但可以通过某种方式来完成上述操作。

感谢您的宝贵时间和帮助!

【问题讨论】:

  • 到目前为止你尝试过什么?输入字符串中哪个元素是父元素,哪个元素是子元素?
  • @pasty 以我对 C# 的了解,我无法尝试任何事情,我不知道从哪里开始。
  • @pasty,我想他想创建一个表达式树。
  • 或使用正则表达式将输入标记为组?
  • @pasty,不确定 RegEx 是否适合这种事情,你肯定会得到组,但我认为这不会有助于将它们组织成层次结构。不过,我已经准备好被证明不是这样了!

标签: c# parent-child calculator


【解决方案1】:

您要查找的内容称为Shunting-yard algorithm。维基百科页面对算法提供了很好的解释。另外,我写了一个 article and a C# program 来为你做这件事,叫做 Math Parser .NET。此外,该库将允许您为几乎任何东西定义自己的函数!

此外,我还编写了a tokenizer 程序,用于根据输入自动生成 C# 或 VB.NET 代码,为您标记您的输入!如果您需要编写自己的数学解析器并且只需要一个标记器来帮助您入门,这将非常有用。

【讨论】:

    【解决方案2】:

    如果你想自己评估它,你需要创建一个二叉树。

    对于父节点,你会给它: 5+5+(3+1+(0+1))+5+5+(3+1+(0+1)) 然后它会创建两个子节点

    .  [+]
    .  /  \
    .[5]  [5+(3+1+(0+1))+5+5+(3+1+(0+1))]
    

    左边没问题。现在需要拆分右边的部分

    .  [+]
    .  /  \
    .[5]  [(3+1+(0+1))+5+5+(3+1+(0+1))]
    

    左边没问题。现在需要拆分右边的部分

    .            [+]
    .  /                 \
    .[(3+1+(0+1))]  [5+5+(3+1+(0+1))]
    

    两部分都需要拆分

    .      [+]
    .  /        \
    .[(3+1)]  [(0+1)]
    

    然后像这样继续

    你最终会得到。

    .  [+]
    .  /  \
    .[5]  [+]
    .     /  \
    .    [5]  [+]
    .         /  \
    .      [+]  [...]
    .     /   \
    .   [+]    [+]
    .  /  \    /  \
    .[3] [1]  [0] [1]
    

    这样就很容易评估结果,找到父母和孩子。

    更多信息:http://en.wikipedia.org/wiki/Binary_expression_tree

    【讨论】:

    • 为了创建/填充树结构,需要某种字符串标记器/解析器。
    【解决方案3】:

    如果您尝试解析该字符串 然后 计算它的值,这 不是 对您来说是一个有效的答案,但如果您的主要目标是计算给定字符串,您可以使用DataTable.Compute 方法。

    使用该函数计算非常容易,您可以查看 stackoverflow 提供的this answer

    var result = new DataTable().Compute("2-3/4*12", null);
    

    我希望你不要为此使用正则表达式。

    有些人在遇到问题时会想“我知道,我会用 正则表达式。”现在他们有两个问题。

    【讨论】:

    • 我也可以使用 Ncalc (ncalc.codeplex.com) 的 .dll,但我想学习自己创建它,但没有某种内置插件。
    【解决方案4】:

    您可以使用 C# 的 lexer+parser (generator) 来构建表达式树。我写了NLT 套件,并且您在示例中包含了很好的入门(参见第 4 号——计算器)。这不科学,但这是一个添加你想要的片段的问题。为了让您了解它的工作原理,这是词法分析器部分(关键部分):

    "(" -> LPAREN;
    ")" -> RPAREN;
    "+" -> PLUS;
    "-" -> MINUS;
    "*" -> MULT, SymbolEnum.MULT; // make the Value equal to MULT as well
    "/" -> DIV;
    "^" -> POWER;
    
    // regex as pattern
    /[0-9]+/ {
                $token = SymbolEnum.NUM;
                $value = Convert.ToDouble($text);
         };
    
    " " { };
    
    "#" { lexer.PushState(StatesEnum.COMMENT); };
    COMMENT /./ { };
    
    /./ -> Error;
    
    %EOF -> EOF;
    

    解析更短:

    s -> e:exp { e };
    
    exp -> LPAREN e:exp RPAREN
           { e }
         | e1:exp PLUS e2:exp
               { new AstNode(SymbolEnum.PLUS, e1, e2) }
         | e1:exp MINUS e2:exp
               { new AstNode(SymbolEnum.MINUS, e1, e2) }
         | e1:exp tok:MULT e2:exp
               { new AstNode((SymbolEnum)tok, e1, e2) }
         | e1:exp DIV e2:exp
               { new AstNode(SymbolEnum.DIV, e1, e2) }
         | e1:exp POWER e2:exp
               { new AstNode(SymbolEnum.POWER, e1, e2) }
         | n:NUM
               { new AstNode(n) }
         | LPAREN Error RPAREN
               // no code
         ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多