C# WPF 制作的计算器,有运算优先级

需求

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

你可能感兴趣的:(C#)