1: 下面是表算术表达式计算的工具,用这个可以很好解决你那个问题,把问题简单化了! public static class ComputeHelper { /// 算术逆波兰表达式计算. public static string ComputeExpresssion(string s) { string S = BuildingRPN(s); string tmp = ""; System.Collections.Stack sk = new System.Collections.Stack(); char c = ' '; System.Text.StringBuilder Operand = new System.Text.StringBuilder(); double x, y; for (int i = 0; i < S.Length; i++) { c = S[i]; if (char.IsDigit(c) || c == '.') { //数据值收集. Operand.Append(c); } else if (c == ' ' && Operand.Length > 0) { #region 运算数转换 try { tmp = Operand.ToString(); if (tmp.StartsWith("-"))//负数的转换一定要小心...它不被直接支持. { //现在我的算法里这个分支可能永远不会被执行. sk.Push(-((double)Convert.ToDouble(tmp.Substring(1, tmp.Length - 1)))); } else { sk.Push(Convert.ToDouble(tmp)); } } catch { return "发现异常数据值."; } Operand = new System.Text.StringBuilder(); #endregion } else if (c == '+'//运算符处理.双目运算处理. || c == '-' || c == '*' || c == '/' || c == '%' || c == '^') { #region 双目运算 if (sk.Count > 0)/*如果输入的表达式根本没有包含运算符.或是根本就是空串.这里的逻辑就有意义了.*/ { y = (double)sk.Pop(); } else { sk.Push(0); break; } if (sk.Count > 0) x = (double)sk.Pop(); else { sk.Push(y); break; } switch (c) { case '+': sk.Push(x + y); break; case '-': sk.Push(x - y); break; case '*': sk.Push(x * y); break; case '/': sk.Push(x / y); break; case '%': sk.Push(x % y); break; case '^': break; } #endregion } else if (c == '!')//单目取反.) { sk.Push(-((double)sk.Pop())); } } if (sk.Count > 1) return "运算没有完成."; if (sk.Count == 0) return "结果丢失.."; return sk.Pop().ToString(); } 待续...
...接上 /// 算术逆波兰表达式.生成. public static string BuildingRPN(string s) { System.Text.StringBuilder sb = new System.Text.StringBuilder(s); System.Collections.Stack sk = new System.Collections.Stack(); System.Text.StringBuilder re = new System.Text.StringBuilder(); char c = ' '; for (int i = 0; i < sb.Length; i++) { c = sb[i]; if (char.IsDigit(c)) re.Append(c); switch (c) { case '+': case '-': case '*': case '/': case '%': case '^': case '!': case '(': case ')': case '.': re.Append(c); break; default: continue; } } sb = new System.Text.StringBuilder(re.ToString());
//对负号进行预转义处理.负号变单目运算符求反. for (int i = 0; i < sb.Length - 1; i++) { if (sb[i] == '-' && (i == 0 || sb[i - 1] == '(')) { sb[i] = '!'; } } // 将中缀表达式变为后缀表达式. re = new System.Text.StringBuilder(); for (int i = 0; i < sb.Length; i++) { if (char.IsDigit(sb[i]) || sb[i] == '.')//如果是数值. { re.Append(sb[i]);//加入后缀式 } else if (sb[i] == '+' || sb[i] == '-' || sb[i] == '*' || sb[i] == '/' || sb[i] == '%' || sb[i] == '^' || sb[i] == '!') { while (sk.Count > 0) //栈不为空时 { c = (char)sk.Pop(); //将栈中的操作符弹出. if (c == '(') //如果发现左括号.停. { sk.Push(c); //将弹出的左括号压回.因为还有右括号要和它匹配. break; //中断. } else { if (Power(c) < Power(sb[i]))//如果优先级比上次的高,则压栈. { sk.Push(c); break; } else { re.Append(' '); re.Append(c); } //如果不是左括号,那么将操作符加入后缀式中. } } sk.Push(sb[i]); //把新操作符入栈. re.Append(' '); } else if (sb[i] == '(')//基本优先级提升 { sk.Push('('); re.Append(' '); } else if (sb[i] == ')')//基本优先级下调 { while (sk.Count > 0) //栈不为空时 { c = (char)sk.Pop(); //pop Operator if (c != '(') { re.Append(' '); re.Append(c);//加入空格主要是为了防止不相干的数据相临产生解析错误. re.Append(' '); } else break; } } else re.Append(sb[i]); } while (sk.Count > 0)//这是最后一个弹栈啦. { re.Append(' '); re.Append(sk.Pop()); } re.Append(' '); return FormatSpace(re.ToString());//在这里进行一次表达式格式化.这里就是后缀式了. } /// 优先级别测试函数. private static int Power(char opr) { switch (opr) { case '+': case '-': return 1; case '*': case '/': return 2; case '%': case '^': case '!': return 3; default: return 0; } } /// 规范化逆波兰表达式. private static string FormatSpace(string s) { System.Text.StringBuilder ret = new System.Text.StringBuilder(); for (int i = 0; i < s.Length; i++) { if (!(s.Length > i + 1 && s[i] == ' ' && s[i + 1] == ' ')) ret.Append(s[i]); else ret.Append(s[i]); } return ret.ToString();//.Replace('!','-'); } }2 应用: string end = ComputeExpresssion("1+2/3-100*2+100");//计算出来
//textBox9.Text = Convert.ToString(tada1);
string tempc = this.textBox5.Text + this.comboBox1.Text + this.textBox6.Text + this.comboBox2.Text + this.textBox7.Text + this.comboBox3.Text + this.textBox8.Text;
DataTable tbl = new DataTable();
string s = tbl.Compute(tempc, null).ToString();
textBox9.Text = s;我改了一个小地方,虽说不是最好的方法,但是也算是一个吧.
1.同18楼,带到SQL中。
2.根据输入动态编译成一个类的方法来调用。
{
DataTable _Table = new DataTable(); decimal _Value1 = 0;
decimal _Value2 = 0;
decimal _Value3 = 0;
decimal _Value4 = 0; if (decimal.TryParse(textBox5.Text, out _Value1) && decimal.TryParse(textBox6.Text, out _Value2) && decimal.TryParse(textBox7.Text, out _Value3) && decimal.TryParse(textBox8.Text, out _Value4))
{
string _Text = _Value1.ToString() + comboBox1.SelectedItem.ToString() + _Value2.ToString() + comboBox2.SelectedItem + _Value3.ToString() + comboBox3.SelectedItem+_Value4.ToString(); object _Value = _Table.Compute(_Text, "");
textBox9.Text = _Value.ToString();
}
}
public static class ComputeHelper
{
/// 算术逆波兰表达式计算.
public static string ComputeExpresssion(string s)
{
string S = BuildingRPN(s);
string tmp = "";
System.Collections.Stack sk = new System.Collections.Stack();
char c = ' ';
System.Text.StringBuilder Operand = new System.Text.StringBuilder();
double x, y;
for (int i = 0; i < S.Length; i++)
{
c = S[i];
if (char.IsDigit(c) || c == '.')
{
//数据值收集.
Operand.Append(c);
}
else if (c == ' ' && Operand.Length > 0)
{
#region 运算数转换
try
{
tmp = Operand.ToString();
if (tmp.StartsWith("-"))//负数的转换一定要小心...它不被直接支持.
{
//现在我的算法里这个分支可能永远不会被执行.
sk.Push(-((double)Convert.ToDouble(tmp.Substring(1, tmp.Length - 1))));
}
else
{
sk.Push(Convert.ToDouble(tmp));
}
}
catch
{
return "发现异常数据值.";
}
Operand = new System.Text.StringBuilder();
#endregion
}
else if (c == '+'//运算符处理.双目运算处理.
|| c == '-'
|| c == '*'
|| c == '/'
|| c == '%'
|| c == '^')
{
#region 双目运算
if (sk.Count > 0)/*如果输入的表达式根本没有包含运算符.或是根本就是空串.这里的逻辑就有意义了.*/
{
y = (double)sk.Pop();
}
else
{
sk.Push(0);
break;
}
if (sk.Count > 0)
x = (double)sk.Pop();
else
{
sk.Push(y);
break;
}
switch (c)
{
case '+':
sk.Push(x + y);
break;
case '-':
sk.Push(x - y);
break;
case '*':
sk.Push(x * y);
break;
case '/':
sk.Push(x / y);
break;
case '%':
sk.Push(x % y);
break;
case '^':
break;
}
#endregion
}
else if (c == '!')//单目取反.)
{
sk.Push(-((double)sk.Pop()));
}
}
if (sk.Count > 1)
return "运算没有完成.";
if (sk.Count == 0)
return "结果丢失..";
return sk.Pop().ToString();
}
待续...
public static string BuildingRPN(string s)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
System.Collections.Stack sk = new System.Collections.Stack();
System.Text.StringBuilder re = new System.Text.StringBuilder(); char c = ' ';
for (int i = 0; i < sb.Length; i++)
{
c = sb[i];
if (char.IsDigit(c)) re.Append(c);
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
case '!':
case '(':
case ')':
case '.':
re.Append(c);
break;
default:
continue;
}
}
sb = new System.Text.StringBuilder(re.ToString());
//对负号进行预转义处理.负号变单目运算符求反.
for (int i = 0; i < sb.Length - 1; i++)
{
if (sb[i] == '-' && (i == 0 || sb[i - 1] == '('))
{
sb[i] = '!';
}
} // 将中缀表达式变为后缀表达式.
re = new System.Text.StringBuilder();
for (int i = 0; i < sb.Length; i++)
{
if (char.IsDigit(sb[i]) || sb[i] == '.')//如果是数值.
{
re.Append(sb[i]);//加入后缀式
}
else if (sb[i] == '+'
|| sb[i] == '-'
|| sb[i] == '*'
|| sb[i] == '/'
|| sb[i] == '%'
|| sb[i] == '^'
|| sb[i] == '!')
{
while (sk.Count > 0) //栈不为空时
{
c = (char)sk.Pop(); //将栈中的操作符弹出.
if (c == '(') //如果发现左括号.停.
{
sk.Push(c); //将弹出的左括号压回.因为还有右括号要和它匹配.
break; //中断.
}
else
{
if (Power(c) < Power(sb[i]))//如果优先级比上次的高,则压栈.
{
sk.Push(c);
break;
}
else
{
re.Append(' ');
re.Append(c);
}
//如果不是左括号,那么将操作符加入后缀式中.
}
}
sk.Push(sb[i]); //把新操作符入栈.
re.Append(' ');
}
else if (sb[i] == '(')//基本优先级提升
{
sk.Push('(');
re.Append(' ');
}
else if (sb[i] == ')')//基本优先级下调
{
while (sk.Count > 0) //栈不为空时
{
c = (char)sk.Pop(); //pop Operator
if (c != '(')
{
re.Append(' ');
re.Append(c);//加入空格主要是为了防止不相干的数据相临产生解析错误.
re.Append(' ');
}
else
break;
}
}
else
re.Append(sb[i]);
}
while (sk.Count > 0)//这是最后一个弹栈啦.
{
re.Append(' ');
re.Append(sk.Pop());
} re.Append(' ');
return FormatSpace(re.ToString());//在这里进行一次表达式格式化.这里就是后缀式了.
} /// 优先级别测试函数.
private static int Power(char opr)
{
switch (opr)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '%':
case '^':
case '!':
return 3;
default:
return 0;
}
} /// 规范化逆波兰表达式.
private static string FormatSpace(string s)
{
System.Text.StringBuilder ret = new System.Text.StringBuilder();
for (int i = 0; i < s.Length; i++)
{
if (!(s.Length > i + 1 && s[i] == ' ' && s[i + 1] == ' '))
ret.Append(s[i]);
else
ret.Append(s[i]);
}
return ret.ToString();//.Replace('!','-');
}
}2 应用:
string end = ComputeExpresssion("1+2/3-100*2+100");//计算出来
SQL语句根据条件用StringBuilder构建就可以了。