C#将父母与孩子分开。 (字符串搜索)

时间:2013-11-21 17:53:46

标签: c# parent-child calculator

我是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"]
}];

这样我可以:

  • 计算'result'数组的长度以获得父项数。
  • 计算'child'数组的长度以获得子数。
  • 通过指向数组索引号来获取元素的内容。

它不一定是这种类型的数组,而是某种方式来做上述事情。

感谢您的时间和帮助!

4 个答案:

答案 0 :(得分:3)

您正在寻找的是Shunting-yard algorithm。维基百科页面提供了对算法的很好的解释。另外,我写了一个article and a C# program来为你做这个叫做Math Parser .NET。此外,该库允许您为几乎任何东西定义自己的功能!

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

答案 1 :(得分: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

答案 2 :(得分:1)

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

使用该函数计算非常简单,您可以查看stackoverflow中给出的this answer

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

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

  

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

答案 3 :(得分:0)

您可以使用lexer + parser(generator)为C#构建表达式树。我写了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
     ;