以中缀形式输入算术表达式,将中缀表达式转换为后缀表达式,再转换成一棵二叉表达式树。
思路:
将中缀表达式转换成后缀表达式,再将后缀表达式反序,以根右左的方式种树,叶子结点均为数值,其它结点均为操作符;再通过中序遍历对表达式进行计算。
代码如下:
#include<iostream>
#include<string>
#include<sstream>
#include<stack>
using namespace std;
double *value;char *fuhao;int len;
//结点
class treenode
{ public:
char f;
double num;
treenode *Lchild, *Rchild;
treenode()
{ f='#';num=0;
Lchild=NULL;
Rchild=NULL;
}
};
//树
class tree
{ public:
treenode *root;
tree()
{ root=NULL;
}
void creat(treenode *&root)
{ if(len>=0)
{ root=new treenode;
if(fuhao[len]!='#')
{
root->f=fuhao[len];
len--;
creat(root->Rchild);
creat(root->Lchild);
}
else
{ root->num=value[len];len--;
}
}
else
{ root=NULL;
}
};
double jisuan(treenode *root); //递归计算
};
double tree::jisuan(treenode *root)//递归计算
{ double m;
if(root!=NULL)
{ if(root->f=='#')
m=root->num;
else
{
if(root->f=='+')
m=jisuan(root->Lchild)+jisuan(root->Rchild);
if(root->f=='-')
m=jisuan(root->Lchild)-jisuan(root->Rchild);
if(root->f=='*')
m=jisuan(root->Lchild)*jisuan(root->Rchild);
if(root->f=='/')
m=jisuan(root->Lchild)*1.0/jisuan(root->Rchild);
}
}
return m;
}
double exchange( string a )
{
istringstream ss( a ); //从string中提取数据,
//把string中以空格隔开的内容提取出来
//string a 转成double
double num;
ss >> num;//把ss的值给num
return num;
}
//主函数
int main()
{
stack< double > s;
string str;
cout<<"请输入计算表达式(不要带空格)"<<endl;
getline(cin,str);
int m=0,n=0;
for(int i=0;i<str.length();i++)
{if(str[i]!='+'&&str[i]!='-'&&str[i]!='*'&&str[i]!='/'&&str[i]!='('&&str[i]!=')'&&str[i]!='.')
if(str[i]<'0'||str[i]>'9'||str[i]==' ')
{ cout<<"非法输入"<<endl;return 0;//输入的不是数字和运算符
}
if(str[i]=='(')
m++;
else if(str[i]==')')
n++;
if(i<str.length()-1)
{ if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='.')
if(str[i+1]=='+'||str[i+1]=='-'||str[i+1]=='*'||str[i+1]=='/'||str[i+1]=='.')
{ cout<<"非法输入"<<endl;return 0;//比如1+-2,两个运算符或小数点连一起的情况
}
if(str[i]=='('&&str[i+1]==')'||str[i]==')'&&str[i+1]=='(')
{ cout<<"非法输入"<<endl;return 0;//输入()或)(连一起
}
}
}
if(m!=n)
{cout<<"非法输入"<<endl;return 0; //()不匹配
}
cout<<"中缀改后缀结果"<<endl;
str=zhongTOhou(str);//zhongTOhou(string) 中缀改成后缀的表达式
cout << str << endl;
int i=0;string p;
fuhao=new char[str.length()];value=new double[str.length()];
stringstream ss(str);//可向该字符串中读数据并且写数据
while( ss >> p )
{
fuhao[i]='#'; //fuhao[i]='#'标记为非符号
if(p[0]=='+'||p[0]=='-'||p[0]=='*'||p[0]=='/')
{
fuhao[i]=p[0];
}//符号都放在fuhao里
else
{
value[i]=exchange(p);
}//数值都放在value里
i++;
}
len=i-1;
tree *T;
T=new tree;
T->creat(T->root);
cout<<T->jisuan(T->root)<<endl;
}
由于中缀转成后缀部分的代码当时是搬的别人的,这里就不放啦
给个测试用例