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 CaculationTest
10 {
11     public partial class Form1 : Form
12     {
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             else
26             {
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,End
14    }
15 
16    class Token
17    {
18        public TokenType Type;
19        public object Value;
20 
21 
22        public Token(TokenType type , object value = null)
23        {
24            Type = type;
25            Value = 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 : Expression
14     {
15         int _value;
16 
17         public UnaryExpress(int value)
18         {
19             _value = value;
20         }
21 
22 
23         public override int GetValue()
24         {
25             return _value;
26         }
27     }
28 
29 
30     class BinaryExpression : Expression
31     {
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 = int.Parse(intStr);
132                         _token= new Token(TokenType.Int, value);
133                         _pos += i;  //解析成功后,更新当前位置
134                         break;
135                     }
136                 }
137             }
138             else
139             {
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

 


验证结果

posted @ 2014-09-26 15:57  伟杰Andy  阅读(347)  评论(0编辑  收藏  举报