3-06. 表示式轉換(25)

old_boy_1991發表於2014-07-20

3-06. 表示式轉換(25)

時間限制
400 ms
記憶體限制
32000 kB
程式碼長度限制
8000 B
判題程式
Standard

算術表示式有字首表示法、中綴表示法和字尾表示法等形式。日常使用的算術表示式是採用中綴表示法,即二元運算子位於兩個運算數中間。請設計程式將中綴表示式轉換為字尾表示式。

輸入格式說明:

輸入在一行中給出不含空格的中綴表示式,可包含+、-、*、\以及左右括號(),表示式不超過20個字元。

輸出格式說明:

在一行中輸出轉換後的字尾表示式,要求不同物件(運算數、運算子號)之間以空格分隔,但結尾不得有多餘空格。

樣例輸入與輸出:

序號 輸入 輸出
1
2+3*(7-4)+8/4
2 3 7 4 - * + 8 4 / +
2
((2+3)*4-(8+2))/5
2 3 + 4 * 8 2 + - 5 /
3
1314+25.5*12
1314 25.5 12 * +
4
-2*(+3)
-2 3 *
5
123
123

#include<iostream>
#include<stack>
#include<string>
using namespace std;

bool isDigitOrPoint(char c)
{
	if((c>='0' && c<='9')|| c=='.')
		return true;
	return false;
}
int main()
{
	string infixExp;  //字首表示式
	string postfixExp=""; //儲存結果,字尾表示式
	stack<char> s; //模擬棧,用來儲存運算子
	
	getline(cin,infixExp);

	int strLen=infixExp.length(); //字首表示式的長度
	int i=0;
	char token; //標記字首表示式的字元
	bool first=true; //是否是第一個數字
	if(infixExp[0]=='+' || infixExp[0]=='-') //第一個數是整數或負數
	{
		postfixExp.append(1,infixExp[0]);
		i++;
	}
	for(;i<strLen;) //迴圈遍歷字首表示式,進行相應的操作
	{
		token=infixExp[i];
		switch(token) //用switch判斷,思路清晰,if else太亂, 注意每個case後都要break..
		{
			case '(':	if(i+1<strLen && ( infixExp[i+1]=='+' || infixExp[i+1]=='-')  ) //括號記憶體在帶‘+’或‘-’的正數或負數
							{
								string temp;
								if(infixExp[i+1]=='-') //如果是負數,需要儲存‘-’符號
									temp.append(1,'-');
								int j=i+2;
								while(j<strLen && isDigitOrPoint(infixExp[j]))  //獲取數字部分
								{
									temp.append(1,infixExp[j]);
									j++;
								}
								postfixExp=postfixExp+" "+temp;
								i=j;
								if(infixExp[i]==')') //如果括號內只是一個正數或負數,跳過右括號,左括號也不用入棧
									i++;
								else //否則
									s.push(token);
						}
						else
						{
							s.push(token);
							i++;
						}
						break;
			case ')':	while(s.size()!=0) //不斷彈出,棧頂元素,直到遇到左括號
							{
								char op=s.top();
								s.pop();           //刪除棧頂元素
								if(op=='(')
									break;
								else
								{
									postfixExp.append(1,' ');
									postfixExp.append(1,op);
								}
						}
						i++;
						break;
			case '+': case '-':case '*':case '/':
							while(true)  //不斷比較token和棧頂元素,直到token入棧
							{
								if(s.empty()  ||   s.top()=='('  ||  (  (token=='*' || token=='/')  && (s.top()=='+' || s.top()=='-')  ))
								{ //如果棧為空,或該運算子的優先順序大於棧頂元素的優先順序,入棧
									s.push(token);
									break;
								}
								else //否則,彈出棧頂元素,繼續比較token與棧頂元素
								{
									postfixExp.append(1,' ');
									postfixExp.append(1,s.top());
									s.pop();
								}
							}
							i++;
							break;
			default:	//數字部分
							string temp="";
							while(i<strLen && isDigitOrPoint(infixExp[i]))  //數字部分
							{
								temp.append(1,infixExp[i]);
								i++;
							}
							if(first)
							{
								postfixExp=postfixExp+temp;
								first=false;
							}
							else
								postfixExp=postfixExp+" "+temp;	//運算子和數字之間以空格分開,不包括正負號
							//cout<<postfixExp<<'A'<<endl;
		}//switch結束
	}//for結束
	
	//彈出棧中元素
	int size=s.size();
	for(i=0;i<size;i++)
	{
		postfixExp.append(1,' ');
		postfixExp.append(1,s.top());
		s.pop();
	}
	cout<<postfixExp<<endl;
	return 0;
} 


相關文章