c#实验,写一个计算器,输入表达式,求值。用到了栈和字符优先级,下面我是由中序遍历转化为后序,也就是逆波兰式求值...界面不是很复杂..
实现思路可以参考这里:http://www.cnblogs.com/souso/articles/1643365.html
直接贴上代码..
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LgmCalculator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BindEvent();
}
private void Form1_Load(object sender, EventArgs e){}
private void button1_Click(object sender, EventArgs e)
{
if (sender is Button) {
Button btn = sender as Button;
if(btn==btn0||btn==btn1||btn==btn2||btn==btn3||btn==btn4||
btn==btn5||btn==btn6||btn==btn7||btn==btn8||btn==btn9||
btn==btnAdd||btn==btnAddSub||btn==btnSub||btn==btnMul||
btn==btnDiv||btn==btnLeft||btn==btnRight||btn==btnPnt){
textBox1.Text += btn.Text;
}else if(btn==btnSin||btn==btnCos||btn==btnTg||btn==btnLn||btn==btnSqrt){
textBox1.Text+=btn.Text;
}
else if (btn == btnPow) {
textBox1.Text+="^";
}
else if (btn == btnBack) {
if (textBox1.Text.Length > 0) {
textBox1.Text = textBox1.Text.Substring(0,textBox1.Text.Length-1);
}
}
else if (btn == btnClear) {
textBox1.Clear();
}
else if (btn == btnCal) { //计算
double result = 0;
Console.WriteLine(textBox1.Text);
string[] str = splitText(textBox1.Text);
for (int k = 0; k < str.Length; k++)
{
Console.WriteLine("str[" + k + "]=" + str[k]);
}
Calculate(str, out result);
Console.WriteLine("Result="+result);
textBox2.Text = result.ToString();
}
}
}
public string[] splitText(string str) {
StringBuilder str1 = new StringBuilder(str.Trim());
string[] str2 = new string[100];
int count = 0;
char ch = ' ';
for (int i = 0; i < str.Length; )
{
StringBuilder sb = new StringBuilder();
ch = str1[i];
if (char.IsDigit(ch) || ch.Equals('.'))
{
while (char.IsDigit(ch) || ch.Equals('.'))
{
sb.Append(ch);
i++;
if (i >= str.Length) break;
ch = str1[i];
}
str2[count++] = sb.ToString();
}
else if (char.IsLetter(ch))
{
while (char.IsLetter(ch))
{
sb.Append(ch);
i++;
if (i >= str.Length) break;
ch = str1[i];
}
if (sb.ToString().Equals("sqrt") || sb.ToString().Equals("sin") || sb.ToString().Equals("cos") || sb.ToString().Equals("tg") || sb.ToString().Equals("ln"))
{
str2[count++] = sb.ToString();
}
else
{
MessageBox.Show("输入错误");
}
}
else
{
if (ch.Equals(' '))
{
i++;
}
else if (ch.Equals('-') || ch.Equals('+') || ch.Equals('*') || ch.Equals('/') || ch.Equals('(') || ch.Equals(')') || ch.Equals('^'))
{
str2[count++] = ch.ToString();
i++;
}
}
}
for (int l = 0; l < count; l++) {
Console.WriteLine("str2["+l+"]="+str2[l]);
}
string []result = new string[count];
int posResult = 0;
double tmp;
Stack<string> stack = new Stack<string>();
stack.Push("#");
for (int i = 0; i < count; i++) {
if (double.TryParse(str2[i], out tmp))
{
result[posResult++] = str2[i];
}
else if (str2[i].Equals("(")){
stack.Push(str2[i]);
}
else if (str2[i].Equals(")")){
string strtmp = stack.Pop();
while(!strtmp.Equals("(")) {
result[posResult++] = strtmp;
strtmp = stack.Pop();
}
if(stack.Peek().Equals("sin")||stack.Peek().Equals("cos")||stack.Peek().Equals("tg")||stack.Peek().Equals("ln")){
result[posResult++] = stack.Pop();
}
}else if(Precedence(stack.Peek())<Precedence(str2[i])){
stack.Push(str2[i]);
}else if(Precedence(stack.Peek())>=Precedence(str2[i])){
if (!(Precedence(stack.Peek()) == Precedence(str2[i]) && Precedence(stack.Peek()) == 3)) {
result[posResult++] = stack.Pop();
while (Precedence(stack.Peek()) >= Precedence(str2[i])) {
result[posResult++] = stack.Pop();
}
}
stack.Push(str2[i]);
}
}
while (!stack.Peek().Equals("#"))
{
result[posResult++] = stack.Pop();
}
string []str3 = new string[posResult];
for (int k = 0; k < posResult; k++) {
str3[k] = result[k];
Console.WriteLine("str3["+k+"]="+str3[k]);
}
return str3;
}
public bool Calculate(string[]str,out double result){
Stack<string> stack = new Stack<string>();
double data1,data2;
result = 0;
stack.Push(str[0]);
for (int i = 1; i < str.Length; i++) {
if(str[i].Equals("+")||str[i].Equals("-")||str[i].Equals("*")||str[i].Equals("/")||str[i].Equals("^")){
data1 = Convert.ToDouble(stack.Pop());
data2 = Convert.ToDouble(stack.Pop());
stack.Push(Operator(data2,str[i],data1).ToString());
}
else if (str[i].Equals("sin") || str[i].Equals("cos") || str[i].Equals("tg") || str[i].Equals("ln")
|| str[i].Equals("sqrt") || str[i].Equals("!"))
{
data1 = Convert.ToDouble(stack.Pop());
stack.Push(Operator(data1, str[i]).ToString());
}
else {
stack.Push(str[i].ToString());
}
}
result = Convert.ToDouble(stack.Pop());
return true;
}
public double Operator(double a,string sign,double b=0){
switch (sign) {
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/": return a / b;
case "^": return Math.Pow(a,b);
case "sqrt": return Math.Sqrt(a);
case "sin": return Math.Sin(a);
case "cos": return Math.Cos(a);
case "tg": return Math.Tan(a);
case "ln": return Math.Log(Math.E,a);
default:
return 0;
}
}
public int Precedence(string sign)
{
switch (sign)
{
case "#": return 0;
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
case "^":
return 3;
case "sin":
case "cos":
case "sqrt":
case "tg":
case "ln":
return 4;
default:
return 0;
}
}
public void BindEvent()
{
foreach (Control ctl in groupBox1.Controls)
{
if (ctl is Button)
{
ctl.Click += new EventHandler(button1_Click);
}
}
}
}
}