您的位置:首页 > 其它

逆波兰表达式计算(后缀表达式,中缀转后缀)

2015-08-28 17:28 621 查看
/*
后缀表达式计算

中缀表达式转后缀表达式
*/
#include<iostream>
#include<cstdlib>
#include<cctype>

using namespace std;

template<class T>
class stack
{
private:
T* base;
T* top;
int stackSize;
public:
stack(int a=100):stackSize(a)
{
base=top=new T[stackSize];
}
~stack()
{
delete [] base;
base=top=NULL;
cout<<"stack析构\n";
}
bool is_empty()const;
bool is_full()const;
bool pop(T &a);
bool push(T a);
int len()const;
};

template<class T>
bool stack<T>::is_empty()const
{
if(base==top)
return true;
else
return false;
}

template<class T>
bool stack<T>::is_full()const
{
if(top-base==stackSize)
return true;
else
return false;
}

template<class  T>
bool stack<T>::push(T a)
{
if(!is_full())
{
*(top++)=a;
return true;
}
else
return false;;

}

template<class T>
bool stack<T>::pop(T& a)
{
if(!is_empty())
{
a=*(--top);
return true;
}
else
return false;
}

template<class T>
int stack<T>::len()const
{
cout<<(int*)base<<endl;
cout<<(int*)top<<endl;
return top-base;
}

double  postfix(char* str) // 计算后缀表达式
{
char c;
stack<double>s;
char bluff[10];

int j=0;
c=str[j++];
while(c!='#')
{
int i=0;
while(isdigit(c) || c=='.')//处理的数是double型的
{
bluff[i++]=c;// 用一块缓存区存储char型数据后转换

if(i>=10)
{
printf("\n输入的数过大\n");
return 1;
}
c=str[j++];
if(' '==c) // 处理数字后的空格,符号后的空格不管
{
bluff[i]='\0';
i=0;
s.push(atof(bluff));
break;
}
}
if('+'==c || '-'==c || '*'==c || '/'==c)
{
double d,e;
s.pop(d);
s.pop(e);
switch(c)
{
case '+':
s.push(d+e);
break;
case '-':
s.push(e-d);// 后出的减去前出的
break;
case '*':
s.push(e*d);
break;
case '/':
if(d !=0)
s.push(e/d);
else
{
printf("\n除数不能为0\n");
return 1;
}
break;
default:
printf("\n符号不能识别\n");
return 1;
}
}

c=str[j++];
}
double ans;
s.pop(ans);

return ans;
}

char* mid2post(char* str, char*& str2)// 人机友好的中缀转换为合适计算机处理的后缀表达式
{
int i=0,j=0;
stack<char>s;
char e;

char c=str[j++];
while(c!='#')
{
while(isdigit(c) || '.'==c)
{
str2[i++]=c;
c=str[j++]; //看下一个数是否还是数字
if(' '==c || '#'==c) //空格结束,这里容易出错
{
str2[i++]=' ';
break;
}
}
if(')'==c) //遇到右括号,栈里肯定有符号
{
s.pop(e);
while('('!=e)
{
str2[i++]=e;
str2[i++]=' ';
s.pop(e);
}
}
else if('+'==c || '-'==c)//
{
if(s.is_empty())//栈空,压栈
{
s.push(c);
}
else //里面的优先级都高于这个+-
{
do
{
s.pop(e);//弹出前面的符号,直到栈空或者遇到左括号
if('('==e)
{
s.push(e);
}
else
{
str2[i++]=e;
str2[i++]=' ';
}
}while('('!=e && !s.is_empty());
s.push(c);// 取出来后别忘了把这个符号再压栈
}
}
else if('*'==c || '/'==c || '('==c)//保证栈里的符号优先级总是较低的
{
s.push(c);
}
if('#'==c)
break;
c=str[j++];
}

while(!s.is_empty())
{
s.pop(e);
str2[i++]=e;
str2[i++]=' ';
}
str2[--i]='#';//'#'之前不要空格,和逆波兰表达式匹配
str2[++i]='\0';
cout<<"后缀表达式:"<<str2<<endl;
return str2;
}

double midfix(char *str)// 计算中缀表达式
{
//cout<<str<<endl;
char* str2=new char[100];
mid2post(str,str2);

double ans=postfix(str2);

delete str2;

return ans;
}

int main()
{
char str[100];
//printf("输入逆波兰表达式,元素之间用空格分开,并以#结束\n");
//cin.getline(str,100);
//cout<<str<<endl;
//printf("\n计算结果是%f\n",postfix(str));

printf("输入中缀表达式,元素之间用空格分开,并以#结束\n");
cin.getline(str,100);
cout<<midfix(str)<<endl;

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