c#--calculator

c#实验,写一个计算器,输入表达式,求值。用到了栈和字符优先级,下面我是由中序遍历转化为后序,也就是逆波兰式求值...界面不是很复杂..

实现思路可以参考这里:http://www.cnblogs.com/souso/articles/1643365.html

直接贴上代码..

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 LgmCalculator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            BindEvent();
        }

        private void Form1_Load(object sender, EventArgs e){}

        private void button1_Click(object sender, EventArgs e)
        {
            if (sender is Button) {
                Button btn = sender as Button;
                if(btn==btn0||btn==btn1||btn==btn2||btn==btn3||btn==btn4||
                    btn==btn5||btn==btn6||btn==btn7||btn==btn8||btn==btn9||
                        btn==btnAdd||btn==btnAddSub||btn==btnSub||btn==btnMul||
                           btn==btnDiv||btn==btnLeft||btn==btnRight||btn==btnPnt){
                               textBox1.Text += btn.Text;              
                }else if(btn==btnSin||btn==btnCos||btn==btnTg||btn==btnLn||btn==btnSqrt){
                        textBox1.Text+=btn.Text;
                }
                else if (btn == btnPow) {
                    textBox1.Text+="^";
                }
                else if (btn == btnBack) {
                    if (textBox1.Text.Length > 0) {
                        textBox1.Text = textBox1.Text.Substring(0,textBox1.Text.Length-1);
                    }
                }
                else if (btn == btnClear) {
                    textBox1.Clear();
                }
                else if (btn == btnCal) {   //计算
                    double result = 0;
                    Console.WriteLine(textBox1.Text);
                    string[] str = splitText(textBox1.Text);
                    for (int k = 0; k < str.Length; k++)
                    {
                        Console.WriteLine("str[" + k + "]=" + str[k]);
                    }
                    Calculate(str, out  result);
                    Console.WriteLine("Result="+result);
                    textBox2.Text = result.ToString();
                }
            }
        }
       
        public string[] splitText(string str) {
            StringBuilder str1 = new StringBuilder(str.Trim());
            string[] str2 = new string[100];
            int count = 0;
            char ch = ' ';
            for (int i = 0; i < str.Length; )
            {
                StringBuilder sb = new StringBuilder();
                ch = str1[i];
                if (char.IsDigit(ch) || ch.Equals('.'))
                {
                    while (char.IsDigit(ch) || ch.Equals('.'))
                    {
                        sb.Append(ch);
                        i++;
                        if (i >= str.Length) break;
                        ch = str1[i];
                    }
                    str2[count++] = sb.ToString();
                }
                else if (char.IsLetter(ch))
                {
                    while (char.IsLetter(ch))
                    {
                        sb.Append(ch);
                        i++;
                        if (i >= str.Length) break;
                        ch = str1[i];
                    }
                    if (sb.ToString().Equals("sqrt") || sb.ToString().Equals("sin") || sb.ToString().Equals("cos") || sb.ToString().Equals("tg") || sb.ToString().Equals("ln"))
                    {
                        str2[count++] = sb.ToString();
                    }
                    else
                    {
                        MessageBox.Show("输入错误");
                    }
                }
                else
                {
                    if (ch.Equals(' '))
                    {
                        i++;
                    }
                    else if (ch.Equals('-') || ch.Equals('+') || ch.Equals('*') || ch.Equals('/') || ch.Equals('(') || ch.Equals(')') || ch.Equals('^'))
                    {
                        str2[count++] = ch.ToString();
                        i++;
                    }
                }
            }

            for (int l = 0; l < count; l++) {
                Console.WriteLine("str2["+l+"]="+str2[l]);
            }

           
            string []result = new string[count];
            int posResult = 0;
            double tmp;
            Stack<string> stack = new Stack<string>();
            stack.Push("#");
            for (int i = 0; i < count; i++) { 
                if (double.TryParse(str2[i], out tmp)) 
                {
                    result[posResult++] = str2[i];
                }
                else if (str2[i].Equals("(")){ 
                    stack.Push(str2[i]);
                }
                else if (str2[i].Equals(")")){
                    string strtmp = stack.Pop();
                    while(!strtmp.Equals("(")) {
                        result[posResult++] = strtmp;
                        strtmp = stack.Pop();
                    }
                    if(stack.Peek().Equals("sin")||stack.Peek().Equals("cos")||stack.Peek().Equals("tg")||stack.Peek().Equals("ln")){
                        result[posResult++] = stack.Pop();
                    }
                }else if(Precedence(stack.Peek())<Precedence(str2[i])){
                    stack.Push(str2[i]);          
                }else if(Precedence(stack.Peek())>=Precedence(str2[i])){
                    if (!(Precedence(stack.Peek()) == Precedence(str2[i]) && Precedence(stack.Peek()) == 3)) {
                        result[posResult++] = stack.Pop();
                        while (Precedence(stack.Peek()) >= Precedence(str2[i])) {
                            result[posResult++] = stack.Pop();
                        }
                    }  
                    stack.Push(str2[i]);
                }
            }

            while (!stack.Peek().Equals("#"))
            {
                result[posResult++] = stack.Pop();
            }

            string []str3 = new string[posResult];
            for (int k = 0; k < posResult; k++) {
                str3[k] = result[k];
                Console.WriteLine("str3["+k+"]="+str3[k]);
            }
            return str3;
        }

        public bool Calculate(string[]str,out double result){
            Stack<string> stack = new Stack<string>();
            double  data1,data2;
            result = 0;
            stack.Push(str[0]);
            for (int i = 1; i < str.Length; i++) { 
                if(str[i].Equals("+")||str[i].Equals("-")||str[i].Equals("*")||str[i].Equals("/")||str[i].Equals("^")){
                    data1 = Convert.ToDouble(stack.Pop());
                    data2 = Convert.ToDouble(stack.Pop());
                    stack.Push(Operator(data2,str[i],data1).ToString());
                }
                else if (str[i].Equals("sin") || str[i].Equals("cos") || str[i].Equals("tg") || str[i].Equals("ln")
                     || str[i].Equals("sqrt") || str[i].Equals("!"))
                {
                    data1 = Convert.ToDouble(stack.Pop());
                    stack.Push(Operator(data1, str[i]).ToString());
                }
                else {
                    stack.Push(str[i].ToString());
                }
            }
            result = Convert.ToDouble(stack.Pop());
            return true;
        }


        public  double Operator(double a,string sign,double b=0){
            switch (sign) {
                case "+": return a + b;
                case "-": return a - b;
                case "*": return a * b;
                case "/": return a / b;
                case "^": return Math.Pow(a,b);
                case "sqrt": return Math.Sqrt(a);
                case "sin": return Math.Sin(a);
                case "cos": return Math.Cos(a);
                case "tg": return Math.Tan(a);
                case "ln": return Math.Log(Math.E,a);
                default:
                    return 0;
            }   
        }

        public int Precedence(string sign)
        {
            switch (sign)
            {
                case "#": return 0;
                case "+":
                case "-":
                    return 1;
                case "*":
                case "/":
                    return 2;
                case "^":
                    return 3;
                case "sin":
                case "cos":
                case "sqrt":
                case "tg":
                case "ln":
                    return 4;
                default:
                    return 0;
            }
        }


        public void BindEvent()
        {
            foreach (Control ctl in groupBox1.Controls)
            {
                if (ctl is Button)
                {
                    ctl.Click += new EventHandler(button1_Click);
                }
            }
        }


    }
}

你可能感兴趣的:(c#--calculator)