今天又修改了几个BUG,加了小数点的处理。
程序主体是封装了转换逆波兰表达式并计算的类。
运行图片:
代码如下(仅后台):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace demo
{
public partial class MainPage : PhoneApplicationPage
{
// 构造函数
public MainPage()
{
InitializeComponent();
}
public class calc//运算类
{
List<string> sourceList = new List<string>();//中缀表达式
List<string> destList = new List<string>();//后缀表达式
private Stack<string> ListStack = new Stack<string>();
public List<string> SourceList { set { sourceList = value; } get { return sourceList; } } //访问器
public List<string> DestList { set { destList = value; } get { return destList; } } //访问器
private void changeList()//中缀转后缀
{
ListStack.Clear();
if (0 == this.sourceList.Count) return;
for (int i = 0; i < sourceList.Count; i++)
{
switch (sourceList[i])
{
case "+":
case "-":
case "*":
case "/":
case "(":
operatorStack(sourceList[i]);
break;
case ")":
operatorStack();
break;
default: //如果是数字,则直接转移
this.DestList.Add(sourceList[i]);
break;
}
}
while (ListStack.Count != 0) DestList.Add(ListStack.Pop());
}
public double Result() //后缀计算结果
{
double Res = 0;
this.changeList();
ListStack.Clear();
foreach (string ch in destList)
{
switch (ch)
{
case "+":
Res = Convert.ToDouble(ListStack.Pop()) + Convert.ToDouble(ListStack.Pop());
ListStack.Push(Convert.ToString(Res));
break;
case "-":
Res = 0 - (Convert.ToDouble(ListStack.Pop()) - Convert.ToDouble(ListStack.Pop()));
ListStack.Push(Convert.ToString(Res));
break;
case "*":
Res = Convert.ToDouble(ListStack.Pop()) * Convert.ToDouble(ListStack.Pop());
ListStack.Push(Convert.ToString(Res));
break;
case "/":
Res = 1 / (Convert.ToDouble(ListStack.Pop()) / Convert.ToDouble(ListStack.Pop()));
ListStack.Push(Convert.ToString(Res));
break;
default://如果是数字,则入栈
ListStack.Push(ch);
break;
}
}
return Res;
}
public bool compare(string a, string b)//比较优先级
{
if (a == "(") return false;//若为左括号,单纯入栈
if (a == "+" || a == "-")
{
if (b == "*" || b == "/")//若后者优先于前者,返回true
return true;
}
else
if (a == "*" && b == "/") return true;
return false;
}
private void operatorStack(string str)
{
if (ListStack.Count != 0)//若栈不为空
{
if (compare(str, this.ListStack.Peek()))
this.DestList.Add(ListStack.Pop());
this.ListStack.Push(str);
}
else
this.ListStack.Push(str);
}
private void operatorStack()//重载,用于单独处理右括号事件
{
string tmp;
while (ListStack.Count != 0)
{
tmp = ListStack.Pop();
if (tmp != "(")
DestList.Add(tmp);
else
return;
}
}
};
calc cal = new calc();//实例化运算类
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
//MessageBox.Show( cal.Result().ToString() );
//========绑定控件数组============
Button[] btnNum = new Button[10];
btnNum[0] = btnNum0;
btnNum[1] = btnNum1;
btnNum[2] = btnNum2;
btnNum[3] = btnNum3;
btnNum[4] = btnNum4;
btnNum[5] = btnNum5;
btnNum[6] = btnNum6;
btnNum[7] = btnNum7;
btnNum[8] = btnNum8;
btnNum[9] = btnNum9;
Button[] btnOperator = new Button[4];
btnOperator[0] = btnOperator1;
btnOperator[1] = btnOperator2;
btnOperator[2] = btnOperator3;
btnOperator[3] = btnOperator4;
// ==========添加事件处理=================
for (int i = 0; i <= 9; i++)
btnNum[i].Click += new System.Windows.RoutedEventHandler(this.btnNums_Click);
for (int j = 0; j <= 3; j++)
btnOperator[j].Click += new System.Windows.RoutedEventHandler(this.btnOperators_Click);
//==========初始化变量====================
}
private void btnNums_Click(object sender, System.EventArgs e)//数字按钮单击事件
{
//==========数字连贯输入===============
if (txtProg.Text == "" && txtResult.Text != "") txtResult.Text = "";//即是判断是否需要重新开始(把上一次计算结果清空)
txtResult.Text += ((Button)sender).Content.ToString();
txtProg.Text += ((Button)sender).Content.ToString();
}
private void btnOperators_Click(object sender, System.EventArgs e)//运算符按钮单击事件
{
if (txtResult.Text != "") cal.SourceList.Add(txtResult.Text);
else if( txtProg.Text[txtProg.Text.Length-1]!=')' ) return;
cal.SourceList.Add(((Button)sender).Content.ToString());
txtProg.Text += ((Button)sender).Content.ToString();
txtResult.Text = "";
}
//等于号处理
private void btnResult_Tap(object sender, GestureEventArgs e)
{
if (txtResult.Text != "") cal.SourceList.Add(txtResult.Text);
else if (txtProg.Text[txtProg.Text.Length - 1] != ')') return;
try
{
txtResult.Text = cal.Result().ToString();
}
catch (Exception ex) { MessageBox.Show("表达式非法,请按Clear后重新输入~"); }
txtProg.Text = "";
cal.SourceList.Clear();
cal.SourceList.Add(txtResult.Text);//保存结果为左值
}
//处理左括号
private void btnLB_Tap(object sender, GestureEventArgs e)
{
try
{
txtProg.Text += ((Button)sender).Content.ToString();
cal.SourceList.Add(((Button)sender).Content.ToString());
} catch(Exception ex){ }
}
//处理右括号
private void btnRB_Tap(object sender, GestureEventArgs e)
{
try
{
txtProg.Text += ((Button)sender).Content.ToString();
cal.SourceList.Add(txtResult.Text);
cal.SourceList.Add(((Button)sender).Content.ToString());
txtResult.Text = "";
}
catch (Exception ex) { }
}
//删除,退格处理
private void btnOpreaBack_Tap(object sender, GestureEventArgs e)
{
if (txtResult.Text != "")
{
txtResult.Text = txtResult.Text.Remove(txtResult.Text.Length - 1);
txtProg.Text = txtProg.Text.Remove(txtProg.Text.Length - 1);
}
}
//清空数据,重新计算
private void btnOpreaClear_Tap(object sender, GestureEventArgs e)
{
txtResult.Text = "";
txtProg.Text = "";
cal.SourceList.Clear();
cal.DestList.Clear();
}
//正负转换
private void btnPM_Tap(object sender, GestureEventArgs e)
{
try
{
double tmp = Convert.ToDouble(txtResult.Text);
tmp = 0 - tmp;
txtResult.Text = tmp.ToString();
}
catch (Exception ex) { }
}
//小数点处理
private void btnDot_Tap(object sender, GestureEventArgs e)
{
if (txtProg.Text == "" && txtResult.Text != "") txtResult.Text = "";//即是判断是否需要重新开始(把上一次计算结果清空)
if (txtResult.Text.Contains('.')) return;
txtResult.Text += ((Button)sender).Content.ToString();
txtProg.Text += ((Button)sender).Content.ToString();
}
}
}