四则运算计算器

今天做个带窗口的C#四则运算计算器

输入中缀表达式(自然表达式) 可以用list来放

先把它变成后缀表达式(逆波兰表达式)

用一个栈放运算符,另一个栈放后缀表达式

运算符优先级:

1:(
2:+ -
3:* /
4:)

从左到右遍历中缀表达式

  • 遇到数字,后缀表达式进栈

  • 遇到运算符:先判断栈是否为空。若是,则直接将此运算符压入栈。若不是,则查看当前栈顶元素。若栈顶元素优先级大于或等于此操作符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式中,并继续进行上述判断。如果不满足上述判断或者栈为空,将这个运算符入栈。

  • 遇到括号:如果是左括号,直接入栈。如果是右括号,弹出栈中第一个左括号后边所有的操作符,并将左括号弹出。(右括号不用入栈)

  • 字符串遍历结束后,如果栈不为空,则弹出栈中所有元素,将它们添加到后缀表达式的末尾,直到栈为空。

计算后缀表达式:

从左到右扫描后缀表达式,如果是数字,放入数字栈。如果是符号,从数字栈中弹出两个数字,第一个取出的数字为右运算数,第二个为左运算数,进行运算。然后将结果放进数字栈中。如此反复,直到读完整个表达式后,留在数字栈中的那个数字就是最终结果。

一部分代码
		List<char> exp;
		
		#region
		获取表达式
		#endregion

		//获取运算符优先级的函数//
		private int getPriority(char ch)
        {
            //获取优先级  
            if (ch == '(') return 1;
            else if (ch == '+' || ch == '-') return 2;
            else if (ch == '*' || ch == '/') return 3;
            else return 4;
        }

		 /按等号开始计算//
        private void button17_Click(object sender, EventArgs e)
        {
            
            #region 将中缀表达式改为后缀表达式

            Stack<char> houzhui = new Stack<char>();
            Stack<char> yunsuanfu= new Stack<char>();

            for (int i = 0; i < exp.Count; i++)
            {
                //数字
                if (exp[i] >= '0' && exp[i] <= '9')
                {
                    houzhui.Push(exp[i]);
                }
                //运算符
                else if(exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/')
                {
                    if (yunsuanfu.Count == 0)
                    {
                        yunsuanfu.Push(exp[i]);
                    }
                    else
                    {
                        while(yunsuanfu.Count != 0)
                        {
                            if(getPriority(yunsuanfu.Peek()) >= getPriority(exp[i])) {
                                houzhui.Push(yunsuanfu.Pop());
                            }  
                             else break;
                        }
                        yunsuanfu.Push(exp[i]);

                    }
                }
                //括号
                else
                {
                    if (exp[i] == '(')
                    {
                        yunsuanfu.Push(exp[i]);
                    }
                    else
                    {
                        while (yunsuanfu.Peek() != '(')
                        {
                            houzhui.Push(yunsuanfu.Pop());
                        }
                        yunsuanfu.Pop();
                    
                    }
                }
                
            }
            while (yunsuanfu.Count != 0)
            {
                houzhui.Push(yunsuanfu.Pop());
            }
            
            //把栈中的后缀表达式挪到一个数组中
            char[] hz = new char[houzhui.Count];
            int length = houzhui.Count;
            while (houzhui.Count > 0)
            {
                hz[houzhui.Count-1] = houzhui.Pop();
            }
            #endregion

            #region 计算后缀表达式
            Stack<double> num = new Stack<double>();
            double num1, num2, num3 = 0; 
            for(int i = 0; i < length ; i++)
            {
                //数字
                if (hz[i] >= '0' && hz[i] <= '9')
                {
                    num.Push(Convert.ToDouble(hz[i].ToString()));
                }
                //符号
                else
                {
                    num2 = num.Pop();
                    num1 = num.Pop();
                    if (hz[i] == '+')
                    {
                        num3 = num1 + num2;
                    }
                    else if (hz[i] == '-')
                    {
                        num3 = num1 - num2;
                    }
                    else if (hz[i] == '*')
                    {
                        num3 = num1 * num2;
                    }
                    else if (hz[i] == '/')
                    {
                        num3 = num1 / num2;
                    }
                    num.Push(num3);
                }
            }

            double  result = num.Pop();
            textBox1.Text = (Convert.ToString(result));

            #endregion
        }
Some notes today

什么时候会发生装箱和拆箱
调用含有object类型的方法的时候,传入值类型的时候就会发生装箱,方法之中处理该参数的时候会发生拆箱。
定义泛型的时候,如果为了通用定义object类型,当添加值类型的时候就会发生装箱和拆箱。

值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。引用类型的对象总是在进程堆中分配(动态分配)。

ArrayList中的项是Object类型,List是泛型(要在声明时声明集合内数据对象类型)

C# out参数在函数内部要赋值。如果是out参数数组的话,用for循环赋值会报错。for循环是不一定进入的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值