C#课要求制作一个有运算优先级的计算器。于是开始制作。
之前学数据结构MOOC的时候就曾经看到过使用堆栈把中缀表达式转换成后缀表达式然后求解。当时没有写过,现在重新学习然后写出这个计算器。
直接上代码。。
思路就是用一个string储存textbox中的字符
按下等号以后将str拆分,并转换成后缀表达式储存在一个stack中
然后将stack中的后缀表达式进行计算。
"HW_Calculator_1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Scarb_Calculator" Height="427" Width="337">
<Grid>
<Grid>
<TextBox Name ="InputTextBox" VerticalAlignment="Top" HorizontalAlignment="Stretch" Margin="16,16,16,0" Height="50" TextWrapping="Wrap">TextBox>
<Grid Margin="10,80,10,10" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
"60">
"60">
"60">
"60">
"60">
Grid.ColumnDefinitions>
<Grid.RowDefinitions>
"60">
"60">
"60">
"60">
"60">
Grid.RowDefinitions>
<Button Name ="Btn7" Content="7" Margin="4" Grid.Column="0" Grid.Row="1" Click="Btn7_Click">Button>
<Button Name ="Btn8" Content="8" Margin="4" Grid.Column="1" Grid.Row="1" Click="Btn8_Click">Button>
<Button Name ="Btn9" Content="9" Margin="4" Grid.Column="2" Grid.Row="1" Click="Btn9_Click">Button>
<Button Name ="BtnDivision" Content="/" Margin="4" Grid.Column="3" Grid.Row="1" Click="BtnDivision_Click">Button>
<Button Name ="BtnLeftBracket" Content="(" Margin="4" Grid.Column="4" Grid.Row="1" Click="BtnLeftBracket_Click">Button>
<Button Name ="Btn4" Content="4" Margin="4" Grid.Column="0" Grid.Row="2" Click="Btn4_Click">Button>
<Button Name ="Btn5" Content="5" Margin="4" Grid.Column="1" Grid.Row="2" Click="Btn5_Click">Button>
<Button Name ="Btn6" Content="6" Margin="4" Grid.Column="2" Grid.Row="2" Click="Btn6_Click">Button>
<Button Name ="BtnMultiple" Content="*" Margin="4" Grid.Column="3" Grid.Row="2" Click="BtnMultiple_Click">Button>
<Button Name ="BtnRightBracket" Content=")" Margin="4" Grid.Column="4" Grid.Row="2" Click="BtnRightBracket_Click">Button>
<Button Name ="Btn1" Content="1" Margin="4" Grid.Column="0" Grid.Row="3" Click="Btn1_Click">Button>
<Button Name ="Btn2" Content="2" Margin="4" Grid.Column="1" Grid.Row="3" Click="Btn2_Click">Button>
<Button Name ="Btn3" Content="3" Margin="4" Grid.Column="2" Grid.Row="3" Click="Btn3_Click">Button>
<Button Name ="BtnMinus" Content="-" Margin="4" Grid.Column="3" Grid.Row="3" Click="BtnMinus_Click">Button>
<Button Name ="BtnEqual" Content="=" Margin="4" Grid.Column="4" Grid.Row="3" Grid.RowSpan="2" Click="BtnEqual_Click">Button>
<Button Name ="Btn0" Content="0" Margin="4" Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="2" Click="Btn0_Click">Button>
<Button Name ="BtnDot" Content="." Margin="4" Grid.Column="2" Grid.Row="4" Click="BtnDot_Click">Button>
<Button Name ="BtnPlus" Content="+" Margin="4" Grid.Column="3" Grid.Row="4" Click="BtnPlus_Click">Button>
<Button Name ="BtnDEL" Content="DEL" Margin="4" Grid.Column="3" Grid.Row="0" Click="BtnDEL_Click">Button>
<Button Name ="BtnAC" Content="AC" Margin="4" Grid.Column="4" Grid.Row="0" Click="BtnAC_Click">Button>
Grid>
<Label x:Name="label" Content="Calculator Made By Scarb" HorizontalAlignment="Left" Margin="19,92,0,0" VerticalAlignment="Top" Height="48" Width="165"/>
Grid>
Grid>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HW_Calculator_1
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private string str = ""; // a string to save data
private static double temp = 0; // a temp variable to save calculated data
// private string text;
private int GetSignPriority(char sign) // get sign priority
{
switch (sign)
{
case '(': // when in stack, the priority of '(' is smallest
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
}
return -1;
}
private int GetObjectTypeFromPostfixExpression(string obj)
{
// if obj is a sign
if (obj == "+")
{
return '+';
}
else if (obj == "-")
{
return '-';
}
else if (obj == "*")
{
return '*';
}
else if (obj == "/")
{
return '/';
}
else // is a number
{
return 0;
}
}
// UI Events
#region simple input Button
private void Btn0_Click(object sender, RoutedEventArgs e)
{
str += "0";
InputTextBox.Text = str;
}
private void Btn1_Click(object sender, RoutedEventArgs e)
{
str += "1";
InputTextBox.Text = str;
}
private void Btn2_Click(object sender, RoutedEventArgs e)
{
str += "2";
InputTextBox.Text = str;
}
private void Btn3_Click(object sender, RoutedEventArgs e)
{
str += "3";
InputTextBox.Text = str;
}
private void Btn4_Click(object sender, RoutedEventArgs e)
{
str += "4";
InputTextBox.Text = str;
}
private void Btn5_Click(object sender, RoutedEventArgs e)
{
str += "5";
InputTextBox.Text = str;
}
private void Btn6_Click(object sender, RoutedEventArgs e)
{
str += "6";
InputTextBox.Text = str;
}
private void Btn7_Click(object sender, RoutedEventArgs e)
{
str += "7";
InputTextBox.Text = str;
}
private void Btn8_Click(object sender, RoutedEventArgs e)
{
str += "8";
InputTextBox.Text = str;
}
private void Btn9_Click(object sender, RoutedEventArgs e)
{
str += "9";
InputTextBox.Text = str;
}
private void BtnPlus_Click(object sender, RoutedEventArgs e)
{
str += "+";
InputTextBox.Text = str;
}
private void BtnMinus_Click(object sender, RoutedEventArgs e)
{
str += "-";
InputTextBox.Text = str;
}
private void BtnMultiple_Click(object sender, RoutedEventArgs e)
{
str += "*";
InputTextBox.Text = str;
}
private void BtnDivision_Click(object sender, RoutedEventArgs e)
{
str += "/";
InputTextBox.Text = str;
}
private void BtnDot_Click(object sender, RoutedEventArgs e)
{
str += ".";
InputTextBox.Text = str;
}
private void BtnLeftBracket_Click(object sender, RoutedEventArgs e)
{
str += "(";
InputTextBox.Text = str;
}
private void BtnRightBracket_Click(object sender, RoutedEventArgs e)
{
str += ")";
InputTextBox.Text = str;
}
private void BtnDEL_Click(object sender, RoutedEventArgs e)
{
if (str.Length > 0)
{
str = str.Substring(0, str.Length - 1);
InputTextBox.Text = str;
}
}
private void BtnAC_Click(object sender, RoutedEventArgs e)
{
str = "";
InputTextBox.Text = str;
}
#endregion
private void BtnEqual_Click(object sender, RoutedEventArgs e)
{
Stack<double> tempStack = new Stack<double>(); // help to calculate postfix expression
Queue<string> postfixExpressionQueue = new Queue<string>(); // save postfix expression
Stack<char> signStack = new Stack<char>(); // save signs
string tempStr = ""; // save numbers
int objType;
double tempDouble;
#region translate to postfix expression
// collect into postfixExpressionStack
for (int i = 0; i < str.Length; i++)
{
if (str[i] <= '9' && str[i] >= '0' || str[i] == '.')
{
tempStr += str[i];
}
else
{
if (tempStr.Length > 0) // if there is a number before the sign, add to stack
{
postfixExpressionQueue.Enqueue(tempStr);
tempStr = "";
}
if (signStack.Count == 0) // sign stack is empty
{
signStack.Push(str[i]);
}
else // isn't empty
{
if (str[i] == '(')
{
signStack.Push('(');
}
else if (str[i] == ')')
{
// pop until ')'
char tempSign;
while (true)
{
tempSign = signStack.Pop();
if (tempSign != '(')
{
postfixExpressionQueue.Enqueue(Convert.ToString(tempSign));
}
else
{
break;
}
}
}
else
{
if (GetSignPriority(str[i]) > GetSignPriority(signStack.Peek()))
{
signStack.Push(str[i]);
}
else
{
while (true)
{
postfixExpressionQueue.Enqueue(Convert.ToString(signStack.Pop()));
if(signStack.Count == 0)
break;
else if (GetSignPriority(str[i]) > GetSignPriority(signStack.Peek()))
break;
}
signStack.Push(str[i]);
}
}
}
}
} // end for
if (tempStr.Length > 0)
{
postfixExpressionQueue.Enqueue(tempStr);
tempStr = "";
}
while (signStack.Count > 0)
{
postfixExpressionQueue.Enqueue(Convert.ToString(signStack.Pop()));
}
#endregion
signStack.Clear();
tempStr = "";
#region calculate the answer by pstfix expression
while (postfixExpressionQueue.Count > 0)
{
objType = GetObjectTypeFromPostfixExpression(postfixExpressionQueue.Peek());
switch (objType)
{
case 0: // if is a number, save to tempStack
tempStack.Push(Convert.ToDouble(postfixExpressionQueue.Dequeue()));
break;
case '+':
postfixExpressionQueue.Dequeue();
tempStack.Push(tempStack.Pop() + tempStack.Pop());
break;
case '-':
postfixExpressionQueue.Dequeue();
tempDouble = tempStack.Pop();
tempStack.Push(tempStack.Pop() - temp);
break;
case '*':
postfixExpressionQueue.Dequeue();
tempStack.Push(tempStack.Pop() * tempStack.Pop());
break;
case '/':
postfixExpressionQueue.Dequeue();
tempDouble = tempStack.Pop();
if (tempDouble != 0.0)
tempStack.Push(tempStack.Pop()/tempDouble);
else
{
MessageBox.Show("Error: zero divisor.");
}
break;
default:
MessageBox.Show("Unknown Error.");
break;
}
}
#endregion
str = Convert.ToString(tempStack.Pop());
InputTextBox.Text = str;
}
}
}
下载地址:http://download.csdn.net/detail/jjhfen00/9330841