中缀表达式计算器

来源:互联网 发布:手机淘宝网旺信在哪 编辑:程序博客网 时间:2024/06/11 20:52

假如给定一个中缀表达式:1+(2-3)*4+10/5利用栈就可以导出后缀表达式123-4*+105/+

导出时注意:操作符入栈,操作数不入栈,在符号“+-*/()”入栈时如果栈中的出现了括号匹配时,需要匹配括号中的符号弹出。如果操作符入栈栈中有级别高或者相等的,就需要将栈中这样级别高或者想到的先出栈,格式肯定是操作数在前,操作符在后的。具体看这个视频:http://v.youku.com/v_show/id_XNTg3MDc0ODQw.html

当得到一个后缀表达式时就很容易的求出表达式的值了,也是用栈计算的,对于123-4*+105/+,从前往后,如果遇到操作数的时候直接入栈,遇到操作符,就从栈中弹出两个操作,那下面的跟上面的那个预算,就可以得到123-4*+105/+的值为-1了,张铭的数据结构堆栈中讲的有。

下面是个中缀表达式的例子:

Stack.h

#include <stdio.h>   #include <malloc.h>   //栈节点数据结构   class DoubleNode  {  friend class DoubleStack;  private:  double value;  DoubleNode *next;  //构造函数   DoubleNode(double value, DoubleNode *p):value(value),next(p){}  };  //栈,用来保存采用后缀表达式进行四则运算时的操作数   class DoubleStack  {  private:  DoubleNode *top;  public:  DoubleStack():top(NULL){}  ~DoubleStack();  void push(double value);  double pop();  bool isEmpty(){return top == NULL;}  double getTop();  };  //栈节点数据结构   class CharNode  {  friend class CharStack;  private:  char value;  CharNode *next;  //构造函数   CharNode(char value, CharNode *p):value(value),next(p){}  };  //栈,用来保存中缀表达式转换成后缀表达式时的运算符   class CharStack  {  private:  CharNode *top;  public:  CharStack():top(NULL){}  ~CharStack();  void push(char value);  char pop();  bool isEmpty(){return top == NULL;}  char getTop();  void makeEmpty();  };  
Stack.cpp

#include "Stack.h"DoubleStack::~DoubleStack(){DoubleNode *p;while (NULL != top){p = top;top = top->next;delete p;}}void DoubleStack::push(double value){top = new DoubleNode(value,top);}double DoubleStack::pop(){if (!isEmpty()){DoubleNode *p;p = top;top = top->next;double nodeValue = p->value;delete p;return nodeValue;}}double DoubleStack::getTop(){return top->value;}CharStack::~CharStack(){CharNode *p;while (NULL != top){p = top;top = top->next;delete p;}}void CharStack::push(char value){top = new CharNode(value,top);}char CharStack::pop(){if (!isEmpty()){CharNode *p;p = top;top = top->next;char nodeValue = p->value;delete p;return nodeValue;}}void CharStack::makeEmpty(){CharNode *p;while (NULL != top){p = top;top = top->next;delete p;}}char CharStack::getTop(){return top->value;}
arithmetic.h

#include <stdio.h>   #include <malloc.h>   #include <string.h>   #include <stdlib.h>   #include "Stack.h"   class Data  {  public:  double num;  char op;  };  class Arithmetic  {  private:  DoubleStack dStack;  //保存四则运算时,后缀表达式中的操作数   CharStack cStack;   //保存中缀表达式转换成后缀表达式过程中的操作符   int isp(char op);   //栈内优先级   int icp(char op);   //栈外优先级   public:  Data post[100];    //保存后缀表达式   int curLen;        //后缀表达式数组的实际长度   void midTopost(char *c);  //把中缀表达式转换成后缀表达式   double calculate();  //进行四则运算   }; 
arithmetic.cpp

#include "arithmetic.h"   void Arithmetic::midTopost(char *c)  {  int i = 0;  int k;  int j;  char tmp;  char a[100];  char num[10];  //下面开始把字符串中的操作符(+-*/)放入后缀表达式   cStack.makeEmpty();  cStack.push('#');  //字符串最后都加一个#   strcat(c, "#");  k = 0;  while (c[k] != '\0')  {  if (c[k] == '+' || c[k] == '-' || c[k] == '*' || c[k] == '/' || c[k] == '(')  {  //如果优先级低,一直退栈,否则入栈   while (isp(cStack.getTop()) > icp(c[k]))  {  post[i++].op = cStack.pop();  }  cStack.push(c[k]);  }  else if (c[k] == ')')  {  //一直退栈到'('   while (isp(cStack.getTop()) >= icp(')'))  {  tmp = cStack.pop();  if (tmp != '(')  {  post[i++].op = tmp;  }  }  }  else if (c[k] == '#')  {  while (isp(cStack.getTop()) > icp('#'))  {  tmp = cStack.pop();  post[i++].op = tmp;  }  }  else if (c[k] >= '0' && c[k] <= '9')  {  //数字,继续往后获取字符,如果是数字,全部拼装到num中,然后转换成double类型   j = 0;  memset(num, 0, 10);  num[j] = c[k];  k = k + 1;  while (c[k] >= '0' && c[k] <= '9')  {  num[++j] = c[k];  k++;  }  post[i].num = atof(num);  post[i].op = '#';  i++;  k--;  }  else  {  //其他非法字符,不处理   }  k++;  }  curLen = i;  }  //栈内优先级,栈内优先级大于栈外优先级   //'('的栈内优先级应该比所有的操作符都小(除了#)   //')'的栈内优先级应该最大   //+-的优先级一致,*/的优先级一致   int Arithmetic::isp(char op)  {  int pri;  switch (op)  {  case '#' : pri = 0;  break;  case '(' : pri = 1;  break;  case '+' : pri = 3;  break;  case '-' : pri = 3;  break;  case '*' : pri = 5;  break;  case '/' : pri = 5;  break;  case ')' : pri = 10;  break;  }  return pri;  }  //栈外优先级   int Arithmetic::icp(char op)  {  int pri;  switch (op)  {  case '#' : pri = 0;  break;  case '(' : pri = 10;  break;  case '+' : pri = 2;  break;  case '-' : pri = 2;  break;  case '*' : pri = 4;  break;  case '/' : pri = 4;  break;  case ')' : pri = 1;  break;  }  return pri;  }  //根据后缀表达式进行四则运算   double Arithmetic::calculate()  {  int i;  double result = 0;  double left, right;  for (i = 0; i < curLen; i++)  {  //如果是数字就入栈   if (post[i].op == '#')  {  dStack.push(post[i].num);  }  else //如果是操作符,就取出两个数字进行运算   {  right = dStack.pop();  left = dStack.pop();  switch (post[i].op)  {  case '+' : dStack.push(left + right);  break;  case '-' : dStack.push(left - right);  break;  case '*' : dStack.push(left * right);  break;  case '/' : dStack.push(left / right);  break;  }  }  }  return dStack.pop();  }  
main.cpp

#include "arithmetic.h"int main(){char tmp[100];printf("please input a arithmetic express:\n");scanf("%s", tmp);Arithmetic ari = Arithmetic();ari.midTopost(tmp);printf("the result = [%f]/n", ari.calculate());system("pause") ;}






原创粉丝点击