2015-10-21 21 views
-5

我想用一个按钮和文本框进行数学运算,当输入文本框操作像25 + 5 + -10 + 7并按下按钮显示结果 我正在尝试这样做但是我不能。 在此代码中,我为每个字符在文本框中,我想存储25在firstvalue参数和+在op参数和5在第二个值参数 并使操作25 + 5 = 30并将其存储在firstvalue参数和存储+ - 在op ,第二个值为10并进行操作,将它存储在第一个值中......等等直到字符串的长度。 但我不知道在哪里以及如何存储第二值我想用一个按钮进行数学运算C#

private void button1_Click(object sender, EventArgs e) 
    { 
     string allValue = textBox1.Text; 
     int firstValue=0; 
     int secondValue=0; 
     string first = string.Empty; 
     string op = string.Empty; 


     foreach (char item in allValue) 
     { 
      if (char.IsNumber(item)) 
      { 
       first += item; 

      } 

      else if(item=='+' || item=='-' || item=='*' || item=='/') 
      { 
       firstValue = Int32.Parse(first); 
       op += item; 
       first = ""; 

       switch (op) 
       { 
        case "+": 
         firstValue = firstValue + secondValue; 
         break; 
        case "-": 
         firstValue = firstValue - secondValue; 
         break; 
        case "+-": 
         firstValue = firstValue +- secondValue; 
         break; 
        case "*": 
         firstValue = firstValue * secondValue; 
         break; 
        case "/": 
         firstValue = firstValue/secondValue; 
         break; 

       } 
      } 
     } 


     MessageBox.Show(firstValue.ToString()); 
    } 
+1

有些图书馆(可能在线的例子)会使这个问题变得非常琐碎。 –

+0

NCalc库是一个:http://ncalc.codeplex.com/ –

+0

这种方法似乎有很多问题,它似乎...主要是,它是一个foreach循环,盲目循环通过这意味着它不接受统计操作顺序。 –

回答

1

可以使用NCalc库。直到你有两个操作数

NCalc.Expression e = new NCalc.Expression(textBox1.Text); 
double value = e.Evaluate(); 
// Next, do something with your evaluated value. 
+0

这不是一个有效的答案。甚至没有一个“我应该如何解析一个方程式”的有效答案?这可能是一个答案:“我几乎不懂任何编程,不想学习,并且有兴趣立即添加两个数字,我该怎么办?”。考虑到推荐一个图书馆在SO中是不重要的,你认为实际上推荐一个图书馆(对于一个甚至没有要求这样的事情的人,甚至没有明确定义最终目标)是关于话题的? – varocarbas

+0

我很抱歉,这个库真的解决了我的问题,但我想通过编程来解决它 –

2

如果要分析从开始字符串结束和分析过程中做计算,那么你不能做两个值之间的计算:你会使用这样的。这意味着您必须等到您找到第二个运算符(或字符串的末尾),直到您可以为第一个运算符进行计算。

当你解析数字时,把它放在secondValue变量中。如果它是第一个值,那么只需将它移动到firstValue并继续获得另一个值,否则按照前一个运算符使用两个值进行计算。

要包含最后一次计算,您可以比字符串中的最后一个字符循环多一步。这允许你的循环在最后一个值之后再运行一次,你可以做最后的计算。尽管如此,它还需要进行更多的检查,以便实际上不会尝试从字符串外部的位置读取数据。

要处理负值,您应该在值中包含该值,而不要使用+-运算符。否则,您还需要--*-/-运营商。

实施例(未测试):

private void button1_Click(object sender, EventArgs e) { 
    string allValue = textBox1.Text; 
    int firstValue = 0; 
    int secondValue = 0; 
    string second = string.Empty; 
    string op = string.Empty; 

    for (int i = 0; i <= allValue.Length; i++) { 
    if (i < allValue.Length && (Char.IsNumber(allValue[i]) || (char == '-' && second.Length == 0))) { 
     second += allValue[i]; 
    } else if (i == allValue.Length || "+-*/".indexOf(allValue[i]) != -1) { 
     secondValue = Int32.Parse(second); 
     if (op.Length > 0) { 
     switch (op) { 
      case "+": firstValue += secondValue; break; 
      case "-": firstValue -= secondValue; break; 
      case "*": firstValue *= secondValue; break; 
      case "/": firstValue /= secondValue; break; 
     } 
     } else { 
     firstValue = secondValue; 
     } 
     if (i < allValue.Length) { 
     op = allValue[i].ToString(); 
     } 
     second = ""; 
    } else { 
     // illegal formula 
    } 
    } 
    MessageBox.Show(firstValue.ToString()); 
} 

注意:此严格计算从左至右和不处理的优先级,例如1+2*3被评估为(1+2)*3,而不是通常使用的1+(2*3)

1

从头开始做所有事情并不容易。在我的简单回答中,我假设您的运营商只有+-*/(包括它们的优先级)。

参考:How to evaluate an infix expression in just one scan using stacks?

首先,你应该分析输入的字符串...我的办法是

public enum TokenType 
{ 
    Operator, 
    Operand 
} 

public class Token 
{ 
    public string Value { get; set; } 
    public TokenType Type { get; set; } 

    public override string ToString() 
    { 
     return Type + " " + Value; 
    } 
} 

IEnumerable<Token> Parse(string input) 
{ 
    return Regex.Matches(input, @"(?<value>\d+)|(?<type>[\+\-\*\/\(\)])").Cast<Match>() 
       .Select(m => m.Groups["value"].Success 
         ? new Token() { Value = m.Groups["value"].Value, Type = TokenType.Operand } 
         : new Token() { Value = m.Groups["type"].Value, Type = TokenType.Operator }); 
} 

Parse方法将返回所有运营商操作数在表达式中

下一步将是使用堆栈

Token Exec(Stack<Token> operatorStack, Stack<Token> operandStack) 
{ 
    var op = operatorStack.Pop(); 
    var t1 = operandStack.Pop(); 
    var t2 = operandStack.Pop(); 

    switch (op.Value) 
    { 
     case "+": return new Token() { Value = (int.Parse(t1.Value) + int.Parse(t2.Value)).ToString(), Type = TokenType.Operand }; 
     case "-": return new Token() { Value = (int.Parse(t2.Value) - int.Parse(t1.Value)).ToString(), Type = TokenType.Operand }; 
     case "*": return new Token() { Value = (int.Parse(t1.Value) * int.Parse(t2.Value)).ToString(), Type = TokenType.Operand }; 
     case "/": return new Token() { Value = (int.Parse(t2.Value)/int.Parse(t1.Value)).ToString(), Type = TokenType.Operand }; 
    } 
    return null; 
} 

int Eval(string input) 
{ 
    var tokens = Parse(input); 

    var operatorStack = new Stack<Token>(); 
    var operandStack = new Stack<Token>(); 
    var precedence = new Dictionary<string, int>() { { "+", 0 }, { "-", 0 }, { "*", 1 }, { "/", 1 } }; 

    foreach (var token in tokens) 
    { 
     if (token.Type == TokenType.Operand) operandStack.Push(token); 
     if (token.Type == TokenType.Operator) 
     { 

      while (operatorStack.Count > 0 && precedence[operatorStack.Peek().Value] >= precedence[token.Value]) 
      { 
       operandStack.Push(Exec(operatorStack, operandStack)); 
      } 
      operatorStack.Push(token); 
     } 
    } 

    while(operatorStack.Count>0) 
    { 
     operandStack.Push(Exec(operatorStack, operandStack)); 
    } 

    return int.Parse(operandStack.Pop().Value); 
} 

现在您可以测试你的代码来计算表达式。

int r1 = Eval("25 - 5"); 
int r2 = Eval("25 - 5*2"); 
int r3 = Eval("25 - 5 + 3*2"); 
int r4 = Eval("25/5 + 7*3"); 
int r5 = Eval("25/5 + 7*3 + 2"); 
int r6 = Eval("25/5 + 7*3 * 2"); 
1

请问这是否适合您?正如在前面的答案中提到的那样,这不关注操作的顺序,还有很多其他的错误检查应该可以完成。

using System.Text.RegularExpressions; 

private void button1_Click(object sender, EventArgs e) 
{ 
    MatchCollection values = Regex.Matches(textBox1.Text, "[0-9]+"); 
    MatchCollection operations = Regex.Matches(textBox1.Text, @"[\/\*\+-]"); 
    if (values.Count == operations.Count + 1) 
    { 
     int total = int.Parse(values[0].Value); 
     if (operations.Count > 0) 
     { 
      for (int index = 1; index < values.Count; index++) 
      { 
       int value = int.Parse(values[index].Value); 
       switch (operations[index - 1].Value) 
       { 
        case "+": 
         total += value; 
         break; 
        case "-": 
         total -= value; 
         break; 
        case "/": 
         total /= value; 
         break; 
        case "*": 
         total *= value; 
         break; 
       } 

      } 
     } 
     MessageBox.Show(total.ToString()); 
    } 
}