首页 > 代码库 > 1.自己写一个计算器demo

1.自己写一个计算器demo

知识点:

1.System.Math.Pow() 实现乘方

2.实现计算器的运算优先级,依次调用的流程

问题:

还未实现“()”功能

解决方案

UI:

 
 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8  9 namespace CaculationTest10 {11     public partial class Form1 : Form12     {13         public Form1()14         {15             InitializeComponent();16         }17 18         private void button_Click(object sender, EventArgs e)19         {20             var text=((Button)sender).Text;21             if (text == "=")22             {23                 Evaluate();24             }25             else26             {27                 txtExpression.Text = txtExpression.Text + text;28             }29         }30 31         private void Evaluate()32         {33             txtExpression.Text = new Caculator().Evaluate(txtExpression.Text).ToString();34         }35 36         private void button16_Click(object sender, EventArgs e)37         {38             txtExpression.Clear();39         }40 41        42     }43 }
Form1.cs
 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4  5 namespace CaculationTest 6 { 7    enum TokenType 8    { 9        Add,Sub,10        Mul,Div,11        Int,12        Expo,13        Start,End14    }15 16    class Token17    {18        public TokenType Type;19        public object Value;20 21 22        public Token(TokenType type , object value = http://www.mamicode.com/null)23        {24            Type = type;25            Value =http://www.mamicode.com/ value;26        }27    }28 }
Token.cs
 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4  5 namespace CaculationTest 6 { 7     /// <summary>   </summary> 8     abstract class Expression 9     {10         public abstract int GetValue();11     }12 13     class UnaryExpress : Expression14     {15         int _value;16 17         public UnaryExpress(int value)18         {19             _value =http://www.mamicode.com/ value;20         }21 22 23         public override int GetValue()24         {25             return _value;26         }27     }28 29 30     class BinaryExpression : Expression31     {32         TokenType _tokenType;33         int _left;34         int _right;35 36 37         public BinaryExpression(TokenType tokenType, Expression left, Expression right)38         {39             _tokenType = tokenType;40             _left = left.GetValue();41             _right = right.GetValue();42         }43 44         public override int GetValue()45         {46             switch (_tokenType)47             {48                 case TokenType.Add:49                     return _left + _right;50                 case TokenType.Sub:51                     return _left - _right;52                 case TokenType.Mul:53                     return _left * _right;54                 case TokenType.Div:55                     return _left / _right;56                 case TokenType.Expo:57                     return Convert.ToInt32(Math.Pow(_left,_right));58                 default:59                     throw new Exception("unexceptional token!");60             }61         }62     }63 }
Expression.cs
  1 using System;  2 using System.Collections.Generic;  3 using System.Text;  4   5   6 namespace CaculationTest  7 {  8     /// <summary>   </summary>  9     class Caculator 10     { 11         string _exp; 12  13         int _pos; 14         Token _token; 15         int _len; 16  17  18         public int Evaluate(string expression) 19         { 20             _exp = expression; 21             _len = expression.Length; 22             var exp = ParseExpression(); 23             return exp.GetValue();  24         } 25  26         Expression ParseExpression() 27         { 28             //先解析一次,解析内容存在_token中 29             ParseToken(); 30             return ParseAddSub(); 31         } 32  33         //解析加减 34         Expression ParseAddSub() 35         { 36             //左操作数为优先级理高的运算符 37             var l = ParseMulDiv(); 38             while (_token.Type == TokenType.Add || _token.Type == TokenType.Sub) 39             { 40                 var t = _token.Type; 41                 ParseToken(); 42                 var r = ParseMulDiv();//解析右操作数 43                 l = new BinaryExpression(t, l, r); 44             } 45             return l; 46         } 47  48         #region 老逻辑 49         ////解析乘除 50         //Expression ParseMulDiv() 51         //{ 52         //    var l = ParseUnary(); 53         //    while (_token.Type == TokenType.Mul || _token.Type == TokenType.Div) 54         //    { 55         //        var t = _token.Type; 56         //        ParseToken(); 57         //        var r=ParseUnary(); 58         //        l = new BinaryExpression(t, l, r); 59         //    } 60         //    return l; 61         //}  62         #endregion 63  64         //解析乘除 65         Expression ParseMulDiv() 66         { 67             var l = ParseExpo(); 68             while (_token.Type == TokenType.Mul || _token.Type == TokenType.Div) 69             { 70                 var t = _token.Type; 71                 ParseToken(); 72                 var r = ParseExpo(); 73                 l = new BinaryExpression(t, l, r); 74             } 75             return l; 76         } 77  78         //解析乘方 79         Expression ParseExpo()  80         { 81             var l = ParseUnary(); 82             while (_token.Type==TokenType.Expo) 83             { 84                 var t = _token.Type; 85                 ParseToken(); 86                 var r = ParseUnary(); 87                 l = new BinaryExpression(t, l, r); 88             } 89             return l; 90         } 91  92         //解析一元表达式(目前只有单个整数) 93         Expression ParseUnary() 94         { 95             Expression ret = null; 96             if (_token.Type == TokenType.Int) 97             { 98                 ret= new UnaryExpress((int)_token.Value); 99             }100 101             //解析完int后,移到下一个token处,即+-*/102             ParseToken();103             return ret;104         }105 106 107         void ParseToken()108         {109             //已结束110             if (_pos >= _len)111             {112                 _token= new Token(TokenType.End);113                 return;114             }115 116             //跳过空格 117             while (_exp[_pos] ==  )118             {119                 _pos++;120             }121             122             //如果以数字开头,解析整数123             if (_exp[_pos] >= 0 && _exp[_pos] <= 9)124             {125                 for (int i = 0; i + _pos <= _len; i++)126                 {127                     //如果以数字结尾,或者到达了数字的边界128                     if( i+_pos==_len||(_exp[_pos + i] < 0 || _exp[_pos + i] > 9))129                     {130                         var intStr = _exp.Substring(_pos, i);131                         var value = http://www.mamicode.com/int.Parse(intStr);132                         _token= new Token(TokenType.Int, value);133                         _pos += i;  //解析成功后,更新当前位置134                         break;135                     }136                 }137             }138             else139             {140                 switch (_exp[_pos])141                 {142                     case +:143                         _token=new Token(TokenType.Add);144                         break;145                     case -:146                         _token = new Token(TokenType.Sub);147                         break;148                     case *:149                         _token=new  Token(TokenType.Mul);150                         break;151                     case /: 152                         _token = new Token(TokenType.Div);153                         break;154                     case ^:155                         _token=new Token(TokenType.Expo);156                         break;157                     default:158                         throw new Exception("unexpected token: " + _exp[_pos]);159                 }160                 _pos++;//解析成功后,更新当前位置161             }162         }163 164     }165 }
Calculator.cs

 


验证结果

1.自己写一个计算器demo