表达式计算的一个例子

表达式计算的演示程序.

下面的表达式计算只支持个位数计数, 用来说明计算原理.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace calc1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.textBox2.Text = ComputeExpression(this.textBox1.Text).ToString();

            bool x0 = true, x1 = false, x2 = false, m0 = true;
            //if ((x0 || x1 || x2) && m0)
            //    this.textBox2.Text = "ok";

            //if (x0 || x1 || x2 && m0)
            //    this.textBox2.Text = "ok";


        }


        /// <summary>
        /// 返回两运算符的优先级
        /// </summary>
        /// <param name="first"></param>
        /// <param name="last"></param>
        /// <returns>">, < , ="</returns>
        private char Precede(char first, char last)
        {
            string operate = "+-*/()#";
            char[,] level = new char[7, 7]{
                    {'>','>','<','<','<','>','>'},
                    {'>','>','<','<','<','>','>'},
                    {'>','>','>','>','<','>','>'},
                    {'>','>','<','<','<','>','>'},
                    {'<','<','<','<','<','=',' '},
                    {'>','>','>','>',' ','>','='},
                    {'<','<','<','<','<',' ','='}
                                              };
            int rows = operate.IndexOf(first);
            int cols = operate.IndexOf(last);
            return level[rows, cols];
        }
        //主要是来展示表中的内容,返回>,<,=.

        //算术表达式的计算算法,参数假设为标准的中缀表达式,否则会出现异常

        /// <summary>
        /// 算符优先算法
        /// </summary>
        /// <param name="infixExpression">中缀表达式</param>
        /// <returns></returns>
        public int ComputeExpression(string infixExpression)
        {
            Stack<int> stackOperand = new Stack<int>();  //操作数栈
            Stack<char> stackOperator = new Stack<char>(); //操作符栈
            stackOperator.Push('#');  //作为栈空的结束符
            infixExpression = infixExpression + "#"; //中缀表达式的结束符
            int temp = 0;
            int result = 0;
            int count = 0;

            char cur = infixExpression[count];

            while (cur != '#' || stackOperator.Peek() != '#') //扫描完算术表达式,并且操作符栈为空
            {
                if (cur == ' ') continue;
                if (IsOperand(cur)) //操作数直接入栈
                {
                    stackOperand.Push(Int32.Parse(cur.ToString()));
                    cur = infixExpression[++count]; //扫描算术表达式下一位
                }
                else
                {
                    switch (Precede(stackOperator.Peek(), cur)) //比较操作符栈顶元素和扫描的当前算符的优先级
                    {
                        //当前运算符优先级较大,则直接入栈,置于栈顶(优先级高需先计算)
                        case '<':
                            stackOperator.Push(cur);
                            cur = infixExpression[++count];
                            break;
                        //等于则表示栈顶元素为左括号,当前字符为右括号
                        case '=':
                            stackOperator.Pop();//弹出左括号
                            cur = infixExpression[++count];
                            break;
                        //当前运算符优先级小,则弹出栈顶运算符并从操作数栈弹出两个操作数
                        case '>':
                            temp = stackOperand.Pop();
                            result = stackOperand.Pop();
                            //注意计算的顺序,计算结果入操作数栈,并且继续比较新的栈顶操作符和当前操作符的优先级
                            stackOperand.Push(Operate(result, temp, stackOperator.Pop()));
                            break;
                    }
                }
            }
            return stackOperand.Peek();
        }

        bool IsOperand(char c)
        {
            int res;
            if (int.TryParse(c.ToString(), out res)) return true;
            return false;
        }

        int Operate(int a, int b, char c)
        {
            int res = 0;
            switch (c)
            {
                case '+':
                    res = a + b;
                    break;
                case '-':
                    res = a - b;
                    break;
                case '*':
                    res = a * b;
                    break;
                case '/':
                    res = a / b;
                    break;
            }
            return res;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


    }
}


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864