您的位置:首页 > 其它

课程设计之算术表达式求值

2010-06-22 20:52 344 查看
//顺序栈
#ifndef STACK_H
#define STACK_H

const int MaxSize=100;

template<class T>
class Stack
{
 public:
  Stack()
  {
   top=-1;
  }
  ~Stack(){}
  void Push(T x);
  T Pop();
  T GetTop();
  bool isEmpty();
  bool isFull();

 private:
  T data[MaxSize];
  int top;

};

#endif

template<class T>
void Stack<T>::Push(T x)
{
 if( Stack<T>::isFull() )
  throw "上溢";
 data[++top]=x;
}

template<class T>
T Stack<T>::Pop()
{
 if( isEmpty() )
  throw "下溢";
 T temp;
 temp=data[top--];
 return temp;
}

template<class T>
bool Stack<T>::isEmpty()
{
 if( top == -1)
  return 1;
 else
  return 0;
}

template<class T>
bool Stack<T>::isFull()
{
 if( top == MaxSize-1 )
  return 1;
 else
  return 0;
}

 

 

 

 

#include<iostream>
using std::cout;
using std::endl;

#include "Stack.h"

//计算一个不含括号的算术表达式,并返回表达式的值
template<class T>
int noBrackt(Stack<T> st)//不含括号的算术表达式为逆序存储在栈st中
{
 int i=0;//'*' 或'/'的个数
 int itemp=0;//'+' 或'-'的个数
 T temp,temp2;
 int back=0;//不含括号的算术表达式的最终结果
 Stack<T> stemp=st;
 //求i和itemp
 while(!stemp.isEmpty())
 {
  temp = stemp.Pop();
  if(temp == '*' || temp == '/')
   i++;
  else
   if(temp == '+' || temp == '-')
    itemp++;
 }
 //将逆序的st转换成正序
 while(!st.isEmpty())
 {
  temp=st.Pop();
  stemp.Push(temp);
 }
 st=stemp;
 //清空stemp
 while(!stemp.isEmpty())
  stemp.Pop();

 //不断扫描*或/并计算,将每次计算结果压回st,计算一次i--,直到i==0
 while(i)
 {
  
  do
  { temp =st.Pop();
   if(temp!='*' && temp!='/')
    stemp.Push(temp);
   if(temp=='*')
   {
    temp2=st.Pop();
    temp=stemp.Pop();
    back=temp*temp2;
    st.Push(back);
    i--;
    break;

   }
   else if(temp == '/')
   {
    temp=stemp.Pop();
    temp2=st.Pop();
    back=temp/temp2;
    st.Push(back);
    i--;
    break;
   }
   
  }
  while(temp!='*' && temp!='/');
 }
 //将保存在stemp中的表达式压回st
 while(! stemp.isEmpty())
 {
  temp = stemp.Pop();
  st.Push(temp);
 }

 //不断扫描+或-并计算,将每次计算结果压回st,计算一次itemp--,直到itemp==0
 while(itemp)
 {
 
   temp =st.Pop();
   if(temp!= '+' && temp!= '-')
    stemp.Push(temp);
   if(temp=='+')
   {
    temp=stemp.Pop();
    temp2=st.Pop();
    back=temp+temp2;
    st.Push(back);
    itemp--;

   }
   else if(temp == '-')
   {
    temp=stemp.Pop();
    temp2=st.Pop();
    back=temp-temp2;
    st.Push(back);
    itemp--;
   }

 }
 return back;//返回表达式的值

 

}

int main()
{
 const int n=23;
 //表达式存在字符数组a[]中
 //char a
={5,'+',2,'*','(',3,'+','(',2,'-',1,')','*',4,'+',8,')'};//5+2*(3+(2-1)*4+8)
 char a[]={2,'-','(','(','(','(',2,'+',2,')','*',2,'+',2,')','-',2,')','+',2,')','/',2};
 //char b[9]={2,'+',3,'*',4,'+',67,'-',90};
 //char c[5]={1,'+',1,'*',1};
 Stack<char> ss,sk,st;

 int count=0;//括号的对数
 int result =0;//算术表达示最终结果
 char templ;//临时变量
 int i=0;
 
 //测试noBrackt()函数
/* for( i=0;i<5;i++)
  sq.Push(c[i]);  
 cout<<noBrackt(sq)<<endl;
*/

 //将数组a[]压栈
 for(i=0;i<n;i++)
 {
  ss.Push(a[i]);
 }

do
{
 //不断从ss出栈,出栈值入临时栈sk,直到遇左括号'('
 do{
  templ=ss.Pop();
  sk.Push(templ);
  if(templ == ')')
   count++;
 }while(templ != '(');
 sk.Pop();

 //清空st,把最内层括号的算术表示式逆序保存在st中
 while(!st.isEmpty())
  st.Pop();
 templ=sk.Pop();
 while(templ != ')')
 {
  st.Push(templ);
  templ=sk.Pop();
 }
 count--;
 result = noBrackt(st);//计算最内层括号的算术表示式st值
 sk.Push(result);//最内层括号的算术表示式的值回压栈sk

}while(count);

//将临时栈的值全部压回原始栈ss中
while(!sk.isEmpty())
{
 templ = sk.Pop();
 ss.Push(templ);
}
result = noBrackt(ss);//计算最后一个表达式的值

//输出表达式和最终结果
for(i=0;i<n;i++)
{
 switch(a[i])
 {
 case '+': 
 case '-': 
 case '*': 
 case '/':
 case '(':
 case ')':
  cout<<a[i];
  break;
 default:
  cout<<int(a[i]);
  break;
 }
}
 cout<<"= "<<result<<endl;

 return 0;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ini 测试 存储 c