我想让数学操作与一个按钮c#

本文关键字:一个 按钮 操作 | 更新日期: 2023-09-27 18:18:46

我想让数学操作与一个按钮和文本框,当键入文本框操作像25+5+-10+7和按下按钮显示我的结果我正在努力做这件事,但我做不到。在此代码中,我为文本框中的每个字符,我想在firstvalue参数中存储25,在op参数中存储+,在secondvalue参数中存储5并将运算25+5=30存储在firstvalue参数中,并将+-存储在op中,10存储在secondvalue中,并将运算25+5=30存储在firstvalue ....中以此类推,直到字符串的长度。但是我不知道在哪里以及如何存储第二个值

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());
    }

我想让数学操作与一个按钮c#

如果您想从头到尾解析字符串并在解析期间进行计算,那么在拥有两个操作数之前,您无法在两个值之间进行计算。这意味着必须等到找到第二个操作符(或字符串的末尾),才能对第一个操作符进行计算。

解析该数字时,将其放入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)

可以使用NCalc库。你可以这样使用它:

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

这对你有用吗?正如在前面的回答中提到的,这并不考虑操作的顺序,而且有很多其他的错误检查应该被完成。

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());
    }
}

从零开始做所有的事情并不容易。在我的简化回答中,我假定您的操作符只有+-*/(包括它们的优先级)。

参考:如何在使用堆栈的一次扫描中评估中缀表达式?

首先你应该解析输入字符串…我的方法是

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");