表示式翻譯
一,對錶達式翻譯的認識:
由中綴變字尾,即由標註的算術表示式變為計算機易識別的式子,並輸出結果.例:中綴為: 9+(3-1)*3+10/2 變為字尾: 9 3 1 – 3 * + 10 2 + / 計算結果為: 20
二 ,轉換的主要思想:
第一步:遇到數字9在後綴表示式中直接輸出,接著是符號”+”入棧 ,
第二步:第三個字元是“(”,依然是符號,這個時候將此符號入棧,接著是數字3,直接輸出,然後是符號“-”,這個時候符號仍然入棧
第三步:接下來是數字1輸出,緊跟著是“)”,此時,我們需要匹配棧裡的“(”,然後再匹配前將棧頂資料依次出棧:
第四步:緊接著是符號“*”,直接入棧:
第五步:遇到數字3,直接輸出,之後是符號“+”,此時棧頂元素是符號“*
第六步:緊接著是數字10,直接輸出,最後是符號“/”,進棧:
第七步:最後一個數字5,這個時候直接輸出5,但是棧裡仍然有資料,此時可以將棧中符號依次出棧。
三,對字尾表示式的計算:
1. 初始化一個空棧。此桟用來對要運算的數字進出使用。
2. 字尾表示式中前三個都是數字,所以9、3、1進棧。
3.
4. 接著是數字3進棧。
5. 後面是乘法“*”,也就意味著棧中3和2出棧,2與3相乘,得到6,並將6進棧。
6. 下面是加法“+”,所以找中6和9出找,9與6相加,得到15,將15進棧。
7. 接著是10與2兩數字進棧。
8. 接下來是符號因此,棧頂的2與10出棧,10與2相除,得到5,將5進棧。
9. 最後一個是符號“+”,所以15與5出找並相加,得到20,將20進棧。
10. 結果是20出棧,棧變為空。
四,核心程式碼
(1) 由字首變字尾:
char* GetBack()//獲取字尾表示式的函式
{
char* middle = new char[30];
char* back = new char[30];
char* backend = back;
InPut(middle);
stack s;
s.push('#');
while (*middle)
{
if (Number(*middle) || *middle =='.')//如果是數字或者小數的話,直接輸出
{
*back = *middle;
back++, middle++;
}
else
{
if (Number(*(back - 1)))//只有他的上一個時數字的話,才繼續給空格
//否則遇到多個操作符,則輸出域會存在多個空格
{
AddSpace(back);
}
if (*middle == ')')//如果右括號的話,輸出所有操作符直到遇到左括號,並拋棄相對應的一堆括號
{
while (s.top() != '(')
{
*back = s.top();
s.pop();
back++; middle++;
AddSpace(back);
}
s.pop();//拋棄左括號
}
else if (*middle == '(')//遇到左括號,則進入棧
{
s.push(*middle); middle++;
}
else if (GetPriority(*middle) >GetPriority(s.top()))//如果棧內的操作符優先順序高於棧外的優先順序,則入棧
{
s.push(*middle); middle++;
}
else if (GetPriority(*middle) <=GetPriority(s.top()))
//如果棧內的操作符優先順序低於或等於棧外的優先順序,輸出棧內的符號,併入棧棧外的符號
{
*back = s.top();
s.pop();
s.push(*middle);
back++; middle++;
AddSpace(back);
}
}
}
while (s.top() != '#')//中綴表示式遍歷完成,但是=棧中還有符號存在,一一出棧輸出
{
AddSpace(back);
*back = s.top();
s.pop(); back++;
}
*back = '\0';
cout << "字尾表示式為: " << backend << endl;
return backend;
}
(2) 字尾表示式的計算:
double CountBack(char*back)
{
stack s;
while (*back)
{
if (Number(*back))//遇到數字
{
s.push(GetNumber(back));//將正確的數字入棧
}
else if (*back == ' ')
{
back++;//遇到空格跳過
}
else
{
double a = s.top();
s.pop();
double b = s.top();
s.pop();
s.push(Cauculate(*back, b, a));//遇到符號時,取棧頂的第二個數和第一個數求解,併入棧
back++;
}
}
while (s.size() >= 2)//最終棧記憶體在的數大於2時,繼續計算,直到只剩下一個數
{
double a = s.top();
s.pop();
double b = s.top();
s.pop();
s.push(Cauculate(*back, b, a));
}
//返回這個數字,既是最終結果
return s.top();
}