利用栈实现加减乘除运算(C#版)

还是有一些小问题....懒得改了,但大体思路还是清晰的,首先定义一个运算符栈,一个数栈。

关于优先级,两个括号(,)优先级最低,其次是+、-,最高的是*、/

关于运算法则,打个比方,"(3+5*4)+3"这个串

首先遇到左括号,直接压入运算符栈,然后是3,直接压入数栈,然后遇到5,压入数栈,遇到*,将其压入运算符栈,遇到右括号,将运算符栈顶的*取出,取出两个数栈栈顶的数,进行乘法运算,将运算结果压入数栈,因为此时运算符栈顶仍不是左括号,取出栈顶的+号,拿出数栈栈顶的两个数,进行加法运算,并将结果压入数栈。此时栈顶是左括号了,那么将左括号弹出栈。此时数栈里还有一个23,运算符栈为空。接着来。此时轮到了+号,直接压入数栈,遇到3,直接压入数栈。此时发现串已经结尾了,但是运算符栈还没有清空。那么就清空吧,把+号拿出来,数栈的23和3拿出来,加法运算,结果压入数栈。此时运算符栈清空,数栈剩个26。这就是最后的结果。是不是很简单但是有一点云里雾里。。

说一下运算规则吧。优先级大家都知道了,优先级从高到低依次是 "*/","+-","()",每当要压运算符时,首先得看看运算符栈里有什么,如果没有,肯定是可以直接压入的,左括号也是可以不管三七二十一直接压入的,除此之外,如果遇到栈顶运算符优先级更高时,是必须将栈顶运算符先取出来运算,直到栈顶元素优先级小于或者等于要压入的运算符的优先级才可压入。比如3*5+5+5,在压入第一个+号时,必须先将栈里的*号先拿出来运算结束后,才能放进去,否则计算结果将是错误的。当压入的是右括号时,必须一直弹运算符栈进行运算,直到遇到左括号为止。当串扫描到末尾时,也必须将运算符栈清空,最后留在数栈的数就是结果。关于小数点,关于复数加减运算,我写的小程序里有了一定的处理,就类似于这样的简单功能。。。。恩,将就看看吧。。程序不完善,不过也懒得改了,毕竟是练习,最近事又多。

下面贴一下源码 

主要用到的几个类和方法:

   类Parser   的parse方法,比如给一个“3+4i”的字符串,返回给你一个3个结点的队,队列第一个元素是一个ComplexNumber对象,实数域为3,队列的第二个元素是“+”号,队列第三个元素是一个ComplexNumber对象,实数域为0,虚数域为4。

    类Operators    用于测试字符是否是运算符,用来进行控制运算,比较运算符优先级....

    类Handler   给一个字符串,他帮你处理,返回给你一个结果。其实就是调一下Parser类的方法去解析一下字符串,然后算一下结果,然后返回结果。

 类ComplexNumber,就是复数类啊,不用说了,提供实数域虚数域,getset方法,加减乘除以及toString()方法

using System;
using System.Collections;
using System.Text;
namespace MySpace{
class Parser{
public static Queue Parse(string input){
char[] arr = input.ToCharArray();
Queue queue = new Queue();
foreach(char x in arr){
queue.Enqueue(x);
}
queue = ParseStringQueue(queue);
return queue;
}

//传入字符串队列,返回封装好的队列。
//ComplexNumber对象或char类型运算符各占用一个结点
private static Queue ParseStringQueue(Queue queue){
Queue secondQ = new Queue();
char c;
StringBuilder sb = null;
string temp;
int count = queue.Count;
bool flag = false; //false表示允许创建新SB对象进行缓存数字字符串
for(int i=0;i<count;i++){
c = (char)queue.Dequeue();

if(!Operators.Contains(c)){
//如果扫描到的不是运算符,则将其加入到buffer尾部
if(!flag){
flag = true;
sb = new StringBuilder();
}
sb.Append(c);
}
if(Operators.Contains(c) || queue.Count == 0){
//如果扫描到的是运算符,则将缓冲区中的串加入队尾

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值