輸入中綴或後綴表達式,輸出值

輸入中綴或後綴表達式,輸出值。

思路: 如果是中綴表達式,則先轉化成後綴表達式。定義兩個棧,一個操作符棧,根據優先級決定是否入棧,另一個棧,將操作數和運算符轉化成後綴式存儲,進行計算。

     如果是後綴表達式,直接進行運算。

#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
*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章