我想让数学操作与一个按钮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());
}
如果您想从头到尾解析字符串并在解析期间进行计算,那么在拥有两个操作数之前,您无法在两个值之间进行计算。这意味着必须等到找到第二个操作符(或字符串的末尾),才能对第一个操作符进行计算。
解析该数字时,将其放入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");