輸入中綴或後綴表達式,輸出值。
思路: 如果是中綴表達式,則先轉化成後綴表達式。定義兩個棧,一個操作符棧,根據優先級決定是否入棧,另一個棧,將操作數和運算符轉化成後綴式存儲,進行計算。
如果是後綴表達式,直接進行運算。
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <cstdlib>
using namespace std;
stack<char> st;//存儲操作符
int priority(char a)//運算符優先級
{
switch(a)
{
case '+':
case '-':
return 1;
break;
case '*':
case '/':
return 2;
break;
case '(':
return 0;
break;
case ')':
return 3;
break;
}
return -1;
}
vector<char> s;//後序存儲棧
void change(string str)
{
int i=0;
while(i!=str.size())
{
if(str[i]>='0'&&str[i]<='9')//數字入棧
s.push_back(str[i]);
else
{
if(str[i]=='(')//第一個爲左括號入操作符棧
st.push(str[i]);
else if(st.size()==0)//運算過程中棧中無字符
st.push(str[i]);
else if(priority(st.top())<priority(str[i]))//優先級的比較
{
if(str[i]==')')
{
while(st.top()!='(')//先將括號裏面的運算符入棧
{
char b=st.top();
st.pop();
s.push_back(b);
}
st.pop();//左括號出棧
}
else
st.push(str[i]);
}
else
{
while(priority(st.top())>=priority(str[i]))
{
if(st.top()=='(')
{
st.pop();
continue;
}
char b=st.top();
st.pop();
s.push_back(b);
if(st.size()==0)
{
st.push(str[i]);
break;
}
}
}
}
++i;
}
while(!st.empty())
{
char t=st.top();
st.pop();
s.push_back(t);
}
}
int fun(string str)
{
stack<char> temp;
int result=0;
int m,n;
for(int i=0;i<s.size();++i)
{
if(isdigit(s[i]))//是數字
{
n=s[i]-'0';
temp.push(n);
}
else
{
m=temp.top();//運算符
temp.pop();
switch(s[i])
{
case '+':
result=temp.top()+m;
break;
case '-':
result=temp.top()-m;
break;
case '*':
result=temp.top()*m;
break;
case '/':
result=temp.top()/m;
break;
}
temp.pop();
temp.push(result);
}
}
return result;
}
int fun1(string str)
{
stack<char> temp;
int result=0;
int m,n;
for(int i=0;i<str.size();++i)
{
if(isdigit(str[i]))
{
n=str[i]-'0';
temp.push(n);
}
else
{
m=temp.top();
temp.pop();
switch(str[i])
{
case '+':
result=temp.top()+m;
break;
case '-':
result=temp.top()-m;
break;
case '*':
result=temp.top()*m;
break;
case '/':
result=temp.top()/m;
break;
}
temp.pop();
temp.push(result);
}
}
return result;
}
int main()
{
while(1)
{
int key;
while(1)
{
cout<<"請輸入:1.中綴表達式;2.後綴表達式;3.退出"<<endl;
cin>>key;
string str;
if(key==1)
{
cout<<"請輸入中綴表達式:"<<endl;
cin>>str;
change(str);
cout<<"運算結果:"<<fun(str)<<endl;
}
else if(key==2)
{
cout<<"請輸入後綴表達式:"<<endl;
cin>>str;
cout<<"運算結果:"<<fun1(str)<<endl;
}
else
return 0;
}
}
return 0;
}
輸入表達式,輸出前序遍歷
輸入:a+b*(c-d)-e/f
輸出:-+a*b-cd/ef
#include <iostream>
#include <stack>
#include <vector>
#include <string>
using namespace std;
typedef struct no
{
char data;
struct no *lchild,*rchild;
}*node;
stack<char> st;
int priority(char a)
{
switch(a)
{
case '+':
case '-':
return 1;
break;
case '*':
case '/':
return 2;
break;
case '(':
return 0;
break;
case ')':
return 3;
break;
}
return -1;
}
vector<char> s;
string change(string str)//轉爲後綴表達式,即後續遍歷
{
int i=0;
string post="";
while(i!=str.size())
{
if(str[i]>='a'&&str[i]<='z')
s.push_back(str[i]);
else
{
if(str[i]=='(')
{
st.push(str[i]);
}
else if(st.size()==0)
st.push(str[i]);
else if(priority(st.top())<priority(str[i]))
{
if(str[i]==')')
{
while(st.top()!='(')
{
char b=st.top();
st.pop();
s.push_back(b);
}
st.pop();
}
else
st.push(str[i]);
}
else
{
while(priority(st.top())>=priority(str[i]))
{
if(st.top()=='(')
{
st.pop();
continue;
}
char c=st.top();
st.pop();
s.push_back(c);
if(st.size()==0)
{
st.push(str[i]);
break;
}
}
}
}
++i;
}
while(!st.empty())
{
char t=st.top();
st.pop();
s.push_back(t);
}
for(i=0;i<s.size();++i)
{
//cout<<s[i]<<" ";
post+=s[i];
}
return post;
}
node create(string post)///根據後序遍歷,建樹
{
node tree;
stack<node>st;
for(int i=0; i<post.length(); i++)
{
if(post[i]!='+'&&post[i]!='-'&&post[i]!='/'&&post[i]!='*')///一定是葉子結點
{
tree=new no();
tree->data=post[i];
tree->lchild=tree->rchild=NULL;
}
else///非葉子結點,賦值其左右子孩子
{
tree=new no();
tree->data=post[i];
tree->rchild=st.top();
st.pop();
tree->lchild=st.top();
st.pop();
}
st.push(tree);
}
return st.top();
}
void pre(node &sa)
{
if(sa!=NULL)
{
cout<<sa->data;
pre(sa->lchild);
pre(sa->rchild);
}
}
int main()
{
cout<<"請輸入中綴表達式:"<<endl;
string inorder,postorder;
node head;
head=new no();
cin>>inorder;
//cout<<in<<endl;
cout<<"轉換爲後綴表達式爲:"<<endl;
postorder=change(inorder);
cout<<postorder<<endl;
//cout<<"構建表達式樹"<<endl;
head=create(postorder);
cout<<"前序遍歷:"<<endl;
pre(head);
cout<<endl;
return 0;
}
/*
a+b*(c-d)-e/f
*/