C# WPF 制作的计算器,有运算优先级
2015-12-06 15:02
459 查看
需求
C#课要求制作一个有运算优先级的计算器。于是开始制作。之前学数据结构MOOC的时候就曾经看到过使用堆栈把中缀表达式转换成后缀表达式然后求解。当时没有写过,现在重新学习然后写出这个计算器。
程序代码
直接上代码。。思路就是用一个string储存textbox中的字符
按下等号以后将str拆分,并转换成后缀表达式储存在一个stack中
然后将stack中的后缀表达式进行计算。
<Window x:Class="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> <ColumnDefinition Width="60"></ColumnDefinition> <ColumnDefinition Width="60"></ColumnDefinition> <ColumnDefinition Width="60"></ColumnDefinition> <ColumnDefinition Width="60"></ColumnDefinition> <ColumnDefinition Width="60"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="60"></RowDefinition> </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> </Window>
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 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> 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相关文章推荐
- c#学前准备
- 初识C#.net
- 基于之前做的一个Demo,总结一下c#操作WebBrowse的一些技巧
- C#中流程控制语句
- C#通过正则表达式实现提取网页中的图片
- BC#65 T5 ZYB's Prime
- C# explicit与implicit
- C#基础篇一
- c#中常用的集合类型及基本用法
- C#设计模式——工厂方法模式
- C# winform 键盘全局事件
- BC#65T4 ZYB's Tree
- C#之飞行棋
- WPF C# 命令 学习
- C# 特性 Attribute
- [C#]VisualStudio2015内置LocalDB
- C#中的跳转语句
- 【转帖】C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- 【转帖】.Net中C#的DllImport的用法
- C#中Abstract和Virtual