綜合實驗(一)簡單計算器

實驗題目

設(shè)計一個支持連續(xù)計算的簡單計算器,其過程包括項目分析,界面設(shè)計,代碼編寫和運行調(diào)試。通過該項目的開發(fā),使讀者進一步了解基于圖形用戶界面的Windows應(yīng)用程序的開發(fā)過程,并通過項目實訓的擴展練習加深印象,為開發(fā)較為復雜的應(yīng)用程序打下基礎(chǔ)。

實驗方案

設(shè)計思路: 有兩個棧 一個存放數(shù)字 一個存放運算符
1、將表達式字符串轉(zhuǎn)換成字符數(shù)組 遍歷字符數(shù)組
2、判斷表達式是否合法,合法的話再進行計算
3、如果是數(shù)字 直接存放到數(shù)字棧
4、如果是符號:分為兩種情況
(1) 如果符號棧為空 直接將符號入棧
(2)如果符號棧不為空
a、當運算符和棧內(nèi)的運算符進行比較 如果當前的運算符的優(yōu)先級低于或者等于棧中的運算符,就需要從數(shù)棧中pop出兩個數(shù),再從符號棧中pop出一個符號,進行運算, 將得到的結(jié)果push進數(shù)棧,然后將當前的符號push符號棧;
b、如果當前的操作符的優(yōu)先級大于棧中的運算符 就直接入符號棧
4、當表達式掃描完畢 就順序從數(shù)棧和符號棧pop出相應(yīng)的數(shù)和符號 并運行
5、最后數(shù)棧中只有一個數(shù)字 即為表達式的結(jié)果


算法流程圖

設(shè)計界面

功能展示

運行調(diào)試圖(一)含有四則的連續(xù)運算表達式

運行調(diào)試圖(二)運行結(jié)果

實驗總結(jié)

本次實驗代碼體量較小,所用到的也是原來在數(shù)據(jù)結(jié)構(gòu)課程中學過的棧,理解起來相對容易?;A(chǔ)部分主要參考書上代碼以及網(wǎng)上的內(nèi)容。拓展部分主要參考網(wǎng)上的內(nèi)容自行理解加以修正。整體碰見以下問題,現(xiàn)加以分析:
1、第一次設(shè)計時并沒有參考書上代碼,自己寫的比較簡單,沒有使用棧。但發(fā)現(xiàn)在擴展功能需要完成優(yōu)先級時很困難,故又利用棧重新設(shè)計。
2、在拓展部分出現(xiàn)sin,cos的計算功能,剛開始只是在原來基礎(chǔ)上簡單添加,后來發(fā)現(xiàn)沒有考慮優(yōu)先級的問題,加到棧里后又發(fā)現(xiàn)這兩個是單目運算符,還要再考慮單目運算符和雙目運算符的判斷。
3、拓展功能還提到了專用領(lǐng)域的計算器,但沒有做出來,希望以后有機會可以接觸一下。
4、第一次實現(xiàn)窗體桌面程序,雖然內(nèi)容比較簡單,但是在設(shè)計過程中不僅僅需要思考怎樣可以得到正確的運算結(jié)果,還需要考量用戶怎么使用會更加舒適,這是自己從來沒有接觸過的。

源碼展示

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace myCalculator
{


    public partial class Form_Main : Form
    {
        string ptr = "";   //算數(shù)表達式
        Stack<int> lastlen = new Stack<int>();//添加操作數(shù)之前的算術(shù)表達式的長度
        Stack<int> lastlenT = new Stack<int>();//添加操作數(shù)之前的文本框的長度
        bool start = true;
        string lastAns = "0";//標志初始化
        Stack<double> nums = new Stack<double>();//操作數(shù)
        Stack<char> ops = new Stack<char>();//運算符


        public Form_Main()
        {
            InitializeComponent();
            textDisplay.Text = "0";
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void TextDisplay_TextChanged(object sender, EventArgs e)
        {

        }

        private void Btn_2_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "2";
            ptr += "2";
        }

        private void Btn_3_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "3";
            ptr += "3";
        }

        private void Btn_4_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "4";
            ptr += "4";
        }

        private void Button6_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "5";
            ptr += "5";
        }

        private void Btn_6_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "6";
            ptr += "6";
        }

        private void Btn_7_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "7";
            ptr += "7";
        }

        private void Btn_8_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "8";
            ptr += "8";
        }

        private void Btn_9_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "9";
            ptr += "9";
        }

        private void Btn_equal_Click(object sender, EventArgs e)
        {
            textDisplay.Clear();
            string ans = Cal(ptr);  //調(diào)用求值算法
            lastlen.Clear();
            lastlenT.Clear();
            lastlen.Push(0);
            lastlenT.Push(0);
            textDisplay.Text += ans;
            ptr = ans;
            double result;
            bool flag = double.TryParse(ans, out result);
            if (!flag || ans == "0") start = true;
        }

        private void Button11_Click(object sender, EventArgs e)//點
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            int len = textDisplay.Text.Length;
            if (len == 0 || (textDisplay.Text[len - 1] < '0' || textDisplay.Text[len - 1] > '9') && textDisplay.Text[len - 1] != '.')
            {
                textDisplay.Text += "0.";
                ptr += "0.";
            }
            else
            {
                textDisplay.Text += ".";
                ptr += ".";
            }
        }

        private void Btn_1_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "1";
            ptr += "1";
        }

        private void Btn_0_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "0";
            ptr += "0";
        }

        private void Btn_add_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length); //沒有添加前的算術(shù)表達式的長度
            lastlenT.Push(textDisplay.Text.Length);
            if (ptr == "")
            {
                textDisplay.Text += "+";
                ptr += "0+";    //把單目運算符“+”改成雙目運算符
            }
            else
            {
                textDisplay.Text += "+";
                ptr += "+";
            }
        }

        private void Btn_clear_Click(object sender, EventArgs e)
        {
            textDisplay.Text = "0";
            ptr = "";
            lastlenT.Clear();
            lastlen.Clear();
            start = true;
        }

        private void Btn_sub_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "-";
            int len = ptr.Length;
            if (len != 0 && (ptr[len - 1] == ')' || (ptr[len - 1] >= '0' && ptr[len - 1] <= '9')))
                ptr += "+-";   //把“-”改成單目運算符
            else ptr += "-";
        }

        private void Btn_multi_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "*";
            ptr += "*";
        }

        private void Btn_div_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "/";
            ptr += "/";
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += "(";
            ptr += "(";

        }

        private void Btn_right_bracket_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            textDisplay.Text += ")";
            ptr += ")";
        }

        private bool check(string str)  //檢查算術(shù)表達式是否匹配
        {
            int jd = 0, num = 0;
            int len = str.Length;
            int st = 0, ed = len - 1;
            while (str[st] == '(' && st < ed) st++;
            while (str[ed] == ')' && ed > 0) ed--;
            if ((str[st] < '0' || str[st] > '9') && str[st] != '-' && str[st] != 'S' && str[st] != 's' && str[st] != 'c') return false;
            if ((str[ed] < '0' || str[ed] > '9') && str[ed] != '!' && str[ed] != '^') return false;
            for (int i = 0; i < len; i++)
            {
                if (str[i] == '+' || str[i] == '*' || str[i] == '/' || str[i] == '%') jd++;
                if ((str[i] >= '0' && str[i] <= '9') || str[i] == '.') jd = 0;
                if (jd >= 2) return false;
            }
            jd = 0;
            for (int i = 0; i < len; i++)
            {
                if (str[i] == '(') jd++;
                else if (str[i] >= '0' && str[i] <= '9' && jd > 0) num++;
                else if (str[i] == ')')
                {
                    if (jd == 0 || num == 0) return false;
                    jd--;
                }
            }
            if (jd > 0) return false;
            return true;
        }
        private int isp(char op)
        {
            // s 表示sin, c 表示cos
            if (op == '#') return 0;
            if (op == '(') return 1;
            if (op == '*' || op == '/' || op == 'c' || op == 's') return 5;
            if (op == '+' || op == '-') return 3;
            if (op == ')') return 7;
            return -1;
        }  //返回棧中算符優(yōu)先級
        private int icp(char op)
        {
            if (op == '#') return 0;
            if (op == '(') return 7;
            if (op == '*' || op == '/') return 4;
            if (op == 'c' || op == 's') return 6;
            if (op == '+' || op == '-') return 2;
            if (op == ')') return 1;
            return -1;
        }//返回棧外算符優(yōu)先級
        private double compute(double l, char op, double r)
        {
            if (op == '+') return l + r;
            if (op == '-') return l - r;
            if (op == '*') return l * r;
            if (op == '/') return l / r;
            return 0;
        } //計算運算符
        
        private bool trans(ref string str)//檢測第一位是不是負號 ref關(guān)鍵字--讓參數(shù)按照引用傳遞
        {
            int num = 0;
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == '-') num++;
                else break;
            }
            str = str.Substring(num);
            if (num % 2 == 0) return false;
            return true;
        }
        private string Cal(string str)  //用堆棧實現(xiàn)中綴表達式求值
        {
            if (str == "") str = "0";
            if (str == "∞") return str;
            if (!check(str)) return "Syntax Error";
            str += '#';
            nums.Clear();
            ops.Clear();
            ops.Push('#');
            for (int i = 0; i < str.Length; i++)
            {
                bool number = false;
                string tmp = "";
                while ((str[i] >= '0' && str[i] <= '9') || str[i] == '.' || str[i] == '-' )
                {
                    number = true;
                    tmp += str[i];
                    i++;
                }
                bool flag;
                if (number)
                {
                    flag = trans(ref tmp);
                    double res;
                    bool success = double.TryParse(tmp, out res);
                    if (flag) res = -res;  //把減號轉(zhuǎn)成負號
                    if (success) nums.Push(res);
                    else return "Syntax Error";
                }
                flag = true;
                while (flag)
                {
                     if (icp(str[i]) > isp((char)ops.Peek()))
                    {
                        ops.Push(str[i]);
                        break;
                    }
                    else if (icp(str[i]) < isp((char)ops.Peek()))
                    {
                        double r = nums.Pop();
                        char op = ops.Pop();
                        if (op == 's' || op == 'c')
                        {
                            if (op == 's') nums.Push(Math.Sin(r * Math.PI / 180));//弧度角度轉(zhuǎn)換
                            else nums.Push(Math.Cos(r * Math.PI / 180));//弧度角度轉(zhuǎn)換
                        }
                        else
                        {
                            double l = nums.Pop();
                            if (op == '/' && r == 0) return "∞";
                            nums.Push(compute(l, op, r));
                        }
                    }
                    else
                    {
                        ops.Pop();
                        break;
                    }
                }
            }
            if (nums.Count > 1) return "Syntax Error";
            lastAns = nums.Pop().ToString();
            return lastAns;
        }

        private void Btn_sin_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            int len = textDisplay.Text.Length;
            if (len > 0 && ((textDisplay.Text[len - 1] >= '0' && textDisplay.Text[len - 1] <= '9') || textDisplay.Text[len - 1] == ')'))
            {
                textDisplay.Text += "*";
                ptr += "*";
            }
            textDisplay.Text += "sin(";
            ptr += "s(";
        }

        private void Btn_cos_Click(object sender, EventArgs e)
        {
            if (start)
            {
                ptr = "";
                textDisplay.Clear();
                start = false;
            }
            lastlen.Push(ptr.Length);
            lastlenT.Push(textDisplay.Text.Length);
            int len = textDisplay.Text.Length;
            if (len > 0 && ((textDisplay.Text[len - 1] >= '0' && textDisplay.Text[len - 1] <= '9') || textDisplay.Text[len - 1] == ')'))
            {
                textDisplay.Text += "*";
                ptr += "*";
            }
            textDisplay.Text += "cos(";
            ptr += "c(";
        }

        private void Btn_backspace_Click(object sender, EventArgs e)
        {
            string str = textDisplay.Text;
            if (str == "Syntax Error" || str == "∞" || str == "Math Error" || str == "Too big")
            {
                textDisplay.Text = "0";
                start = true;
                return;
            }
            textDisplay.Text = textDisplay.Text.Substring(0, lastlenT.Pop());
            if (ptr.Length != 0)
            {
                ptr = ptr.Substring(0, lastlen.Pop());
            }
            if (textDisplay.Text.Length == 0)
            {
                textDisplay.Text = "0";
                lastlenT.Push(0);
                start = true;
            }
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 數(shù)據(jù)結(jié)構(gòu)與算法 1.算法的有窮性是指( )。答案:A A)算法程序的運行時間是有限的 B)算法程序所處理的數(shù)據(jù)量是...
    織夢學生閱讀 3,680評論 1 15
  • 一、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡單分配策略的問題地址空間不隔離內(nèi)存使用效率低程序運行的地址不確定 關(guān)于...
    SeanCST閱讀 8,107評論 0 27
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,695評論 0 5
  • 秋雨聲聲陪葉落, 寒霜片片染楓紅。 白云遠遠送鴻雁, 暮色沉沉落鎮(zhèn)中。 街道縱橫清掃凈, 高樓廣廈若繁星。 中央廣...
    云逸1108閱讀 263評論 0 2
  • 春風一直在吹,早上和太陽肩并肩起來,中午和陽光一起明媚微笑,夕陽落,日暮降,她吹得更待勁了,吹落了樹葉,吹來了綠芽...
    邑蝶閱讀 188評論 0 0

友情鏈接更多精彩內(nèi)容