洛谷 P1175 表示式的轉換

2022-07-15 15:39:14 字數 4586 閱讀 9468

平常我們書寫的表示式稱為中綴表示式,因為它將運算子放在兩個運算元中間,許多情況下為了確定運算順序,括號是不可少的,而中綴表示式就不必用括號了。

字尾標記法:書寫表示式時採用運算緊跟在兩個運算元之後,從而實現了無括號處理和優先順序處理,使計算機的處理規則簡化為:從左到右順序完成計算,並用結果取而代之。

例如:8–(3+2*6)/5+4可以寫為:8 3 2 6*+5/–4+

其計算步驟為:8 3 2 6 * + 5 / – 4 +

8 3 12 + 5 / – 4 +

8 15 5 / – 4 +

8 3 – 4 +

5 4 +

編寫乙個程式,完成這個轉換,要求輸出的每乙個資料間都留乙個空格。

就一行,是乙個中綴表示式。輸入的符號中只有這些基本符號「0123456789+-*/^()」,並且不會出現形如2*-3的格式。

表示式中的基本數字也都是一位的,不會出現形如12形式的數字。

所輸入的字串不要判錯。

若干個字尾表示式,第i+1行比第i行少乙個運算子和乙個運算元,最後一行只有乙個數字,表示運算結果。

8–(3+2*6)/5+4

832

6 * + 5 / – 4 + 83

12 + 5 / – 4 + 815

5 / – 4 +

83 – 4 +

54 +

9

中綴表示式(或中綴記法)是乙個通用的算術或邏輯公式表示方法, 操作符是以中綴形式處於運算元的中間(例:3 + 4),中綴表示式是人們常用的算術表示方法。與字首表示式(例:+ 3 4)或字尾表示式(例:3 4 +)相比,中綴表示式不容易被計算機解析,但仍被許多程式語言使用,因為它符合人們的普遍用法。與字首或字尾記法不同的是,中綴記法中括號是必需的。計算過程中必須用括號將操作符和對應的運算元括起來,用於指示運算的次序。

字首表示式是一種沒有括號的算術表示式,與中綴表示式不同的是,其將運算子寫在前面,運算元寫在後面。為紀念其發明者波蘭數學家jan lukasiewicz,字首表示式也稱為「波蘭式」。例如,- 1 + 2 3,它等價於1-(2+3)。

字尾表示式,指的是不包含括號,運算子放在兩個運算物件的後面,所有的計算按運算子出現的順序,嚴格從左向右進行(不再考慮運算子的優先規則)。

該題的第乙個步驟就是將乙個中綴表示式轉換為字尾表示式,可以按以下步驟來進行,但是如果有負數存在的話,可能有一點小小的改動。

(1)init兩個棧:運算子棧op和儲存過程結果的棧r;

(2)乙個乙個字元的遍歷輸入的表示式,直到遍歷到表示式的最右邊;

2.1)如果遇到數,直接入棧r,此時注意負數的判斷;

2.2)如果遇到運算子,比較其與運算子棧op棧頂運算子的優先順序:

如果運算子棧op為空,或運算子棧op棧頂運算子為左括號'(',或該運算子的優先順序比棧頂運算子的高,則直接將此運算子入棧;

否則,將運算子棧op棧頂的運算子彈出並壓入到棧r中,再次比較其與運算子棧op棧頂運算子的優先順序;

2.3) 如果遇到括號:

如果遇到左括號'(',則直接壓入運算子棧op;

如果遇到右括號')',則依次彈出運算子棧op棧頂的運算子,並壓入棧r,直到遇到左括號為止,並丟棄這對括號;

(3)將運算子棧op中剩餘的運算子依次彈出並壓入棧r;

(4)依次彈出棧r中的元素並逆序輸出。

例如,將輸入樣例中的中綴表示式8–(3+2*6)/5+4'轉換為字尾表示式的過程如下:

遍歷時的元素

運算子棧op(top->bottom)

棧r(top->bottom)步驟8

empty

82.1--

82.2

(( -

82.3

3( -

3 82.1

++ ( -

3 82.2

2+ ( -

2 3 8

2.1*

* + ( -

2 3 8

2.2 *優先順序比+高

6* + ( -

6 2 3 8

2.1)

-+ * 6 2 3 8

2.3 依次彈出運算子棧op棧頂的運算子

// -

+ * 6 2 3 8

2.2 /優先順序比-高

5/ -

5 + * 6 2 3 8

2.1+

+- / 5 + * 6 2 3 8

2.2 +優先順序比/低,不比-高,棧空4+

4 - / 5 + * 6 2 3 8

2.1\0

empty

+ 4 - / 5 + * 6 2 3 8

3最後的輸出為'8 3 2 6 * + 5 / - 4 +'(注意需要逆序輸出)。

該題的第二個步驟就是逐步計算乙個字尾表示式,可以按以下步驟來進行:

(1)init兩個棧:儲存資料的棧op(名字不太好,但可以用上面步驟的棧)和儲存過程結果的棧r;

(2)從op彈出元素,直到op為空;

2.1)如果遇到數,直接入棧r;

2.2)如果遇到運算子,用運算子對棧頂元素和次頂元素做相應的計算(次頂元素 運算子 棧頂元素),然後輸出:

棧op(top->bottom)

棧r(top->bottom)

8 3 2 6 * + 5 / - 4 +

empty

* + 5 / - 4 +

6 2 3 8

+ 5 / - 4 +

12 3 8

5 / - 4 +

15 8

/ - 4 +

5 15 8

- 4 +

3 84 +5+

4 5empty

9了解了相關知識,用棧就很好實現了,我認真寫了乙個棧……還是為了資料結構的考試……

#include #include 

#include

#include

#include

#define stack_size 100

#define stackincrement 10

#define ok 1

#define error 0typedef

struct

myelemtypeelemtype;

typedef

intstatus;

using

namespace

std;

class

stack

//status push(elemtype e)

//資料結構的寫法

void

push(elemtype e)

//return ok;

} status pop(elemtype *e)

elemtype* top(void

)

void printttob(void

)

if(bottom->isoperator==0

) cout

<< bottom->data;

else

cout

<< (char)(bottom->data);

}void printbtot(void

)

if((top-1)->isoperator==0

) cout

<< (top-1)->data;

else

cout

<< (char)((top-1)->data);

}void destroystack(void

)while(top!=bottom);

top=null;

bottom=null;

stacksize=0

; }

private

: elemtype *bottom;

elemtype *top;

intstacksize;

};stack op,r;

intmain()

}else

if(c[i]=='(')

else

if(c[i]=='

)') //

如果遇到右括號')',則依次彈出運算子棧op棧頂的運算子,並壓入棧r,直到遇到左括號為止,並丟棄這對括號;

while(op.pop(&temp) && temp.data!='('

) r.push(temp);

else

temp.data=(int

)c[i];

temp.isoperator=1

; op.push(temp);

}isnum=1

; }

}while(r.pop(&temp))

op.push(temp);

op.printttob();

cout

else

如果遇到數,直接入棧r;

r.push(temp);

}return0;

}

洛谷P1175 表示式的轉換(表示式計算)

平常我們書寫的表示式稱為中綴表示式,因為它將運算子放在兩個運算元中間,許多情況下為了確定運算順序,括號是不可少的,而中綴表示式就不必用括號了。字尾標記法 書寫表示式時採用運算緊跟在兩個運算元之後,從而實現了無括號處理和優先順序處理,使計算機的處理規則簡化為 從左到右順序完成計算,並用結果取而代之。例...

中綴表示式求值(P1175 表示式的轉換)

思路 先中綴表示式轉字尾,再對字尾表示式求值。中綴表示式轉字尾 o n 掃一遍輸入的中綴表示式 1.遇到數 直接輸出 2.遇到左括號 左括號直接入棧。3.遇到運算符號 利用建立的符號棧,棧內總原則為高階運算壓在低階運算之上。4.遇到加 減 乘 除 乘方,按照正常的運算優先順序處理 可以看一下p198...

Luogu1175 表示式的轉換 表示式樹

平常我們書寫的表示式稱為中綴表示式,因為它將運算子放在兩個運算元中間,許多情況下為了確定運算順序,括號是不可少的,而中綴表示式就不必用括號了。字尾標記法 書寫表示式時採用運算緊跟在兩個運算元之後,從而實現了無括號處理和優先順序處理,使計算機的處理規則簡化為 從左到右順序完成計算,並用結果取而代之。例...