Windows Form簡易計算機實現(下)

來源:互聯網
上載者:User

標籤:思路   com   break   ges   nal   png   idt   訪問   img   

  陸陸續續更新這個計算機用了一個禮拜了,今天無論如何也要把它更完。筆者有點追求完美,再者每天都有課,晚上還有作業,還有每晚都會寫一些其他的博文。

  上一次漏了寫如何?計算的。思路如下:

  之前得到一個棧2stack2,裡面存的是逆波蘭式。但是注意了,式子是反過來的。因為棧只能從棧頂寫入,從棧頂拿出。所以,必須把棧2的數反過來。

  下面是轉換的代碼:

        //        //將棧2數值倒過來        //        private void UpSideDown()        {            string[] strTemp = stack2.ToArray();                        //將棧stack2數值臨時儲存在數組裡            stack2.Clear();                                             //將棧stack2清空            for(int i=strTemp.Length-1;i>=0;i--)            {                stack2.Push(strTemp[i]);            }        }

 

  將棧的數值倒過來之後,我們就可以進行計算了,計算的思路如下:按步驟

  1:從棧頂取元素,如果是數字直接存入新棧 2:如果是操作符,則不存入,將新棧的前兩個元素依次取出,先取出的數字放在運算子右邊,後取出的放在左邊 3:計算的結果放回新棧。重複以上步驟,知道計算完。

  注意!新棧儲存的數字,所以要注意棧的類型。

        //        //計算四則運算        //        public double DoMath()        {            var stackTemp = new Stack<double>();            try            {                while (myStack2.Count != 0)                {                    if (!IfNumber(myStack2.Peek()))                    {                        double d1 = stackTemp.Pop();                        double d2 = stackTemp.Pop();                        switch (myStack2.Pop())                        {                            case "+":                                stackTemp.Push(d2 + d1);                                break;                            case "-":                                stackTemp.Push(d2 - d1);                                break;                            case "*":                                stackTemp.Push(d2 * d1);                                break;                            case "/":                                stackTemp.Push(d2 / d1);                                break;                        }//end switch                    }//end if                    else                    {                        stackTemp.Push(Convert.ToDouble(myStack2.Pop()));                    }                }//end while                return stackTemp.Pop();            }            catch            {                return 0;            }        }

 

  四則混合運算的大體步驟和解決思路就這麼多,現在開始解決如何確保使用者在亂輸入公式以及得到的公式該怎麼解析(前面提到的問題:就是當接受了加括弧的一元運算子比如:1+(-2)。轉換得到的式子是不能正確計算的。)

  思路一:怎麼解決使用者亂輸入數字

  用棧儲存使用者每次按的按鍵內容,除了第一次輸入外,在每次輸入的時候與棧頂元素進行比較。如果連續兩次輸入操作符,則視第二次有效:

        private string str = "";                                    //聲明切定義一個Null 字元串,用於在label顯示使用者輸入        Stack<string> tempStack = new Stack<string>();              //聲明一個數組,用去儲存使用者輸入        //判斷使用者點擊是否有效        public void IfValid(string s)        {            if (tempStack != null)            {                if (Calculate.IfNumber(s))                        //如果使用者按得是數字,則輸入有效                {                    tempStack.Push(s);                }                else                {                    if (!Calculate.IfNumber(tempStack.Peek()))       //如果使用者連續兩次按的是操作符,則視第二次有效                    {                        tempStack.Pop();                        tempStack.Push(s);                    }                    else                        tempStack.Push(s);                }                            }//end if            else            {                tempStack.Push(s);            }            str = "";            string[] tempStr = tempStack.ToArray();            //將得到的數組反轉            for (int i = 0; i < tempStr.Length / 2; i++)            {                string temp = tempStr[i];                tempStr[i] = tempStr[tempStr.Length - i - 1];                tempStr[tempStr.Length - i - 1] = temp;            }            foreach (var item in tempStr)                str += item;            label1.Text = str;        }        private void button1_Click(object sender, EventArgs e)        {            IfValid(button1.Text);        }        private void button2_Click(object sender, EventArgs e)        {            IfValid(button2.Text);        }

  筆者有很多地方都用到將數組元素前後倒過來的代碼,但卻沒有將其寫成獨立函數,造成代碼的冗餘。

 

  這裡代碼是寫在Form1裡的,用到了ReversePolish的IsNumber的方法,因為是不同類的,而且沒有ReversePolish就直接調用,所以要把之前定義的修飾private 改成public static修飾才能直接調用。

  思路二:當接受了加括弧的一元運算子比如:1+(-2)。通過逆波蘭法則轉換得到的式子是不能正確計算的。

  把式子進行解析,寫成:1+(0-2)的形式!

  代碼如下:

  

       string[] strAnalysis;                                           //存放解析完原始計算公式之後的公式        string[] str;                                                   //string數組str用於存放原始計算公式//        //解析原始計算公式        //        public void Analysis()        {            var stackTemp = new Stack<string>();            int count = 0;            try            {                while (count < strAnalysis.Length)                {                    if (strAnalysis[count] == "(" && (strAnalysis[count + 1] == "-" || strAnalysis[count + 1] == "+"))     //如果公式運算元(的後一位運算元是+或則-,                    {                        stackTemp.Push(strAnalysis[count]);                        stackTemp.Push("0");                        count++;                    }                    else if (!IfNumber(strAnalysis[count]))                    {                        stackTemp.Push(strAnalysis[count]);                        count++;                    }                    else if (IfNumber(strAnalysis[count]))                    {                        string strTemp = "";                        while (count < strAnalysis.Length && IfNumber(strAnalysis[count]))          //如果是數字,包括小數點.,則拼成一個字串,直到遇到一個操作符或則數組遍曆完畢                        {                            strTemp += strAnalysis[count];                            count++;                        }                        stackTemp.Push(strTemp);                    }                }            }            catch            {                stackTemp = null;            }                        str = stackTemp.ToArray();            //反轉字串數組            for (int i = 0; i < str.Length / 2; i++)            {                string temp = str[i];                str[i] = str[str.Length - i - 1];                str[str.Length - i - 1] = temp;            }        }        

  大體思路思路就這麼多了,總之是問題逐一突破,把解決的問題方案寫成方法,最後湊在一起就成功了。以上的代碼並不是所有的代碼,筆者只是想把自己的思路分享一下。因為我猜如果我把所有代碼都貼出來是要花很長時間看的。畢竟每個人的思維不一樣。本人就不擅長讀別人的代碼T T。

  提示:一般遇到訪問記憶體,比如取棧壓棧訪問棧頂的代碼,最好上異常處理,因為很容易就出現錯誤。

  歡迎大家提出質疑!

 

Windows Form簡易計算機實現(下)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.