逆波兰表达式计算

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。

#include<iostream>
#include<assert.h>
using namespace std;
class Stack
{
public:
 Stack()
  :_array(NULL)
  , _size(0)
  , _capacity(0)
 {}
 Stack(const Stack<T>& s)
  :_array(new T[s._capacity])
  , _size(s._size)
  , _capacity(s._capacity)
 {
  for (int i = 0; i < s._size; ++i)
  {
   _array[i] = s._array[i];
  }
 }
 Stack& operator=(Stack s)
 {
  swap(_array, s._array);
  swap(_size, s._size);
  swap(_capacity, s._capacity);
  return *this;
 }
 ~Stack()
 {
  //cout << "~Stack()" << endl;
  delete[] _array;
  _size = _capacity = 0;
 }
 void Push(const T& x)
 {
  _CheckCapacity();
  _array[_size++] = x;
 }
 void Pop()
 {
  assert(!IsEmpty());
  --_size;
 }
 bool IsEmpty()
 {
  return _size == 0;
 }
 bool IsFull()
 {
  return _size == _capacity;
 }
 size_t Size()
 {
  return _size;
 }
 const T&  Top()
 {
  return _array[_size - 1];
 }
protected:
 void  _CheckCapacity()
 {
  if (_size == _capacity)
  {
   _capacity = 2 * _capacity + 3;
   T* tmp= new T[_capacity];
   if (_array)
   {
    for (int i = 0; i < _size; ++i)
    {
     tmp[i] = _array[i];
    }
    delete[] _array;
   }
   _array = tmp;
  }
 }
public:
 T *_array;
 size_t _size;
 size_t _capacity;
};
enum SYMBOL
{
 ADD,
 SUB,
 MUL,
 DIV
};
enum OpType
{
 OP_NUM,
 OP_SYMBOL
};
struct Cell//单元
{
 OpType _type;
 int _value;
};
//RNP逆波兰表达式
//12 3 4 + * 6 - 8 2 / +
//82
Cell RNPArray[11]=
{
 { OP_NUM, 12 }
 ,{ OP_NUM, 3 }
 ,{OP_NUM, 4}
 ,{OP_SYMBOL,ADD}
 ,{OP_SYMBOL, MUL}
 , {OP_NUM,6}
 , {OP_SYMBOL,SUB}
 , {OP_NUM,8}
 , {OP_NUM,2}
 , {OP_SYMBOL,DIV}
 , {OP_SYMBOL,ADD}
};
int CountRNP(Cell* RNPExp, size_t size)
{
 Stack<int> s;
 for (size_t i = 0; i < size; ++i)
 {
  if (RNPExp[i]._type == OP_NUM)
  {
   s.Push(RNPExp[i]._value);
  }
  else
  {
   int right = s.Top();
   s.Pop();
   int left = s.Top();
   s.Pop();
   switch (RNPExp[i]._value)
   {
   case ADD:
    s.Push(left + right);
    break;
   case SUB:
    s.Push(left - right);
    break;
   case MUL:
    s.Push(left * right);
    break;
   case DIV:
    //保证right!=0
   // assert(!right);
    s.Push(left / right);
    break;
   }
  }
 }
 return s.Top();
}
int main()
{
 //栈的特点:后进先出,只能从尾部进行操作
 cout << CountRNP(RNPArray, 11) << endl;
 system("pause");
 return 0;
}


你可能感兴趣的:(表达式,逆波兰)