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

需求

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

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个简单的 C# WPF 时钟的示例代码: XAML 部分: ```xml <Window x:Class="WpfClock.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPF Clock" Height="200" Width="200"> <Grid> <Ellipse Width="100" Height="100" Fill="White"/> <Canvas Margin="50"> <Line X1="50" Y1="50" X2="50" Y2="10" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="90" Y2="50" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="45" Y2="85" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="55" Y2="85" Stroke="Black" StrokeThickness="2"/> <Line X1="50" Y1="50" X2="10" Y2="50" Stroke="Red" StrokeThickness="1"/> <Line X1="50" Y1="50" X2="50" Y2="90" Stroke="Red" StrokeThickness="1"/> </Canvas> <TextBlock x:Name="txtTime" Margin="70,100,0,0" FontSize="20"/> </Grid> </Window> ``` C# 部分: ```cs using System; using System.Windows; using System.Windows.Threading; namespace WpfClock { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { txtTime.Text = DateTime.Now.ToString("hh:mm:ss tt"); } } } ``` 这个时钟使用了一个 `Ellipse` 控件来表示时钟的外形,使用 `Canvas` 控件来添加时钟的刻度和指针,使用 `TextBlock` 控件来显示当前时间。`DispatcherTimer` 用于每秒更新一次当前时间。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值