C# 简易计算器

编写如下界面的简易计算器界面代码:

using System;
using System.Windows.Forms;
using exp;
namespace calculator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        enum symbol { plus,dec,mult,div};

        private void button1_Click(object sender, EventArgs e)
        {
            Button currentButton = sender as Button;
            if(currentButton!= null)
            {
                textBox1.Text += currentButton.Text;
            }
      
        }
        
        private void equal_Click(object sender, EventArgs e)
        {
            //string text = textBox1.Text;
            // string[] value = text.Split(new char[4] { '+','-','x','/'});
            //foreach (string i in value) MessageBox.Show(i);

            //com.change();
            compute cs = new compute(textBox1.Text);
            cs.PostFix();
            textBox1.Text=cs.scanpost().ToString();
         }

        private void clear_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
            
        }
    }
}
View Code

功能实现:(创建computeexp类文件)

思路:数字以及运算符按钮共享一个点击事件,则文本框里的字符串为中缀表达式,将中缀表达式求值返回值到文本框即可。

在computeexp类中初始化操作符栈stack等,然后编写方法转化为后缀表达式,然后对后缀表达式求值

转化为后缀表达式string:
扫描中缀表达式,对于多位数字依次添加到string中,并在每个数字结束后添加空格作为数字的分界,对于操作符按照其优先级判断是否添加到stack或string中,注意括号()不出现在后缀表达式内。

优先级高的要先计算,所以运算符stack栈顶元素的优先级最高,因为要先pop出来先进行计算

后缀求值:
扫描后缀表达式,处理字符型数字为demical类型,进操作数栈,遇到运算符,从操作数栈中弹出两个数运算,计算结果再次push操作数栈,直至扫描结束,同时操作数栈顶即为最后结果

    问题:对于dowhile()循环条件的编写不清楚

                          1.do while 先执行一次在判断循环条件是否成立,成立继续执行,不成立跳出循环

  2.注意:在进行按照string位数扫描时,如果是多位数字,如何让下一次遍历的位数正确,不出现没有扫描到操作符的问题,导致后缀表达式多个数字分 界符导致错误

      功能实现代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace exp
{
    class compute
    {
        private string exp;
        private string postexp;
        private Stack<char> oper=new Stack<char>();
        private Stack<decimal> opernum=new Stack<decimal>();
        public compute()
        {
            exp = "((34.51+5x2)+3)/5+6/4x2+3";
            exp += '#';
            postexp = "";
            oper.Push('#');
        }
        public int prority(char c)
        {
         
            if (c == 'x' || c == '/') return 3;
            if (c == '+' || c == '-') return 2;
            // if (c == ')') return 0;
            if (c == '(') return 1;//遇到(直接入栈
            if (c == '#') return 0;
            return -1;
        }

        public void PostFix()
        {
            int i = 0;
            while(i<exp.Length)
            {
                     if (exp[i]=='#')
                        {
                                while(true)
                                {
                                    if (oper.Peek() == '#') break;
                                    char tem = oper.Peek();
                                    postexp += tem;
                                    oper.Pop();       
                                }

                        }
                         else
                        {
                                if (exp[i] >= '0' && exp[i] <= '9')
                            {//若为操作数
                                postexp += exp[i];
                                //加上小数点和多位数
                                while (exp[i + 1] >= '0' && exp[i + 1] <= '9')
                                {
                                    i++;
                                    postexp += exp[i];

                                }

                                    postexp += ' ';     

                            }
                                else
                                {//若为其他符号
                                    switch (exp[i])
                                    {
                                        case '(': oper.Push(exp[i]); break;
                                        case ')':
                                            while (true)
                                            {
                                        if (oper.Peek() == '(') break;
                                                char cur = oper.Peek();
                                                postexp += cur;
                                                oper.Pop();
                                            }
                                            oper.Pop();
                                            break;
                            case '.':
                                postexp = postexp.Substring(0,postexp.Length-1);//截取字符串
                                postexp += '.';break;
                            default:
                                            if (prority(oper.Peek()) < prority(exp[i])) oper.Push(exp[i]);
                                            else
                                            {
                                                while (true)
                                                {
                                                    if (prority(exp[i]) > prority(oper.Peek())) break;
                                                    char tem = oper.Peek();
                                                    postexp += tem;
                                                    oper.Pop();
                                                }
                                                oper.Push(exp[i]);
                                            }
                                            break;

                                    }//switch

                                }//numelse

                }//#else
                   
                        i++;
                    
             }//while
     
            }//函数

        public void show()
        {
            Console.WriteLine(exp);
            Console.WriteLine(postexp);
        }
        public decimal computepost(char c)
        {
            decimal first, second,res=0;
            second = opernum.Pop();//第二操作数
            first = opernum.Pop();//第一操作数
            if (c == '+') res = first + second;
            if (c == '-') res = first - second;
            if (c == 'x') res = first * second;
            if (c == '/') res = first / second;
            return res;

        }
        public decimal scanpost()
        {
            int i = 0;
            while (i <= postexp.Length - 1) 
            {
                if(postexp[i]>='0'&&postexp[i]<='9')
                {//读到操作数
                    decimal num = 0;
                    string nu ="";
                    nu += postexp[i];
                    while(postexp[i+1]!=' ')
                    {
                        i++;
                        nu += postexp[i];
                        
                    }
                    num = Convert.ToDecimal(nu);
                    opernum.Push(num);
                }
                else if(postexp[i]!=' ')
                {//读到操作符或空格
                        opernum.Push(computepost(postexp[i]));
                }
                i++;
            } 
            Console.WriteLine("result="+opernum.Peek());
            return oper.Peek();
        }
        
    }
}
View Code

 

posted @ 2017-09-14 20:29  LarryXXXXXXXXX  阅读(917)  评论(0编辑  收藏  举报