LeetCode 表示式求值

2021-07-03 13:43:07 字數 3465 閱讀 3890

表示式求值是指給定乙個表示式字串,求得表示式最後的值。

例如給定表示式:3 + 2 * (4 + 1),通過表示式求值後得到的值為13

這裡之所以寫leetcode是因為做lc中題目時碰到類似題目,所以把這個通用問題寫一寫以作記錄。

這裡只介紹使用棧的版本,其他方法還有待發掘。

其實解決思路是挺明確的,大體是用兩個棧分別儲存操作符運算元,然後順序解析字串,關鍵在於操作符的操作。這裡分為兩種情況:

操作符的優先順序:如果遇到的操作符優先順序大於棧頂操作符的優先順序,則操作符入棧。

的問題:如果遇到反括號,則除了遵守優先順序規定外,遇到要一起消除。

迴圈完成後,根據棧中的內容進行計算,最後得到的數為結果。

注:這裡沒有考慮小數情況(包括除法)和式子中有符號的情況。

雖然程式並不複雜,思路也很直接。但是在實現中需要注意不要使用某個數來代替優先順序,如』『+』的優先順序是1『 等。下面會做詳細說明:

首先來看優先順序表:

priorities[ '+' ][ '-' ] = '>' ;

priorities[ '+' ][ '+' ] = '>' ;

priorities[ '+' ][ '*' ] = '<' ;

priorities[ '+' ][ '/' ] = '<' ;

priorities[ '+' ][ '(' ] = '<' ;

priorities[ '+' ][ ')' ] = '>' ;

priorities[ '-' ][ '-' ] = '>' ;

priorities[ '-' ][ '+' ] = '>' ;

priorities[ '-' ][ '*' ] = '<' ;

priorities[ '-' ][ '/' ] = '<' ;

priorities[ '-' ][ '(' ] = '<' ;

priorities[ '-' ][ ')' ] = '>' ;

priorities[ '*' ][ '-' ] = '>' ;

priorities[ '*' ][ '+' ] = '>' ;

priorities[ '*' ][ '*' ] = '>' ;

priorities[ '*' ][ '/' ] = '>' ;

priorities[ '*' ][ '(' ] = '<' ;

priorities[ '*' ][ ')' ] = '>' ;

priorities[ '/' ][ '-' ] = '>' ;

priorities[ '/' ][ '+' ] = '>' ;

priorities[ '/' ][ '*' ] = '>' ;

priorities[ '/' ][ '/' ] = '>' ;

priorities[ '/' ][ '(' ] = '<' ;

priorities[ '/' ][ ')' ] = '>' ;

priorities[ '(' ][ '+' ] = '<' ;

priorities[ '(' ][ '-' ] = '<' ;

priorities[ '(' ][ '*' ] = '<' ;

priorities[ '(' ][ '/' ] = '<' ;

priorities[ '(' ][ '(' ] = '<' ;

priorities[ '(' ][ ')' ] = '=' ;

可以看到這個優先順序是沒有傳遞性的,例如『(』 和 『+』,對應表中都是』<』。舉個栗子:

棧頂是』(『,遇上『+』,應該將+入棧,則 『+』 > 『(』

棧頂是』+』, 遇上『(』,應該將(入棧,則 『+』 < 『(『

所以用數字來表示優先順序是不合適的。

下面的的**借鑑這個部落格

寫的比較清楚

#include 

#include

#include

using

namespace

std ;

// 運算子優先順序表

unordered_map

< char , unordered_map

< char , char > > priorities ;

// 初始化運算子優先順序定義資料

void initpriorities( )

// 計算2個運算元 加減乘除 的結果。

float calculate( float operand1 , float operand2 , char operator )

else

if ( operator == '-' )

else

if ( operator == '*' )

else

if ( operator == '/' )

return ret ;

}// 計算 加減,不帶括號的表示式

float evaluateexpression( const

string& str )

else

if ( ch == '+' || ch == '-' || ch == '*' || ch == '/' ||

ch == '(' || ch == ')' )

// 當前遇到的操作符作為操作符2,將和之前遇到的操作符(作為操作符1)進行優先順序比較

const

char& opt2 = ch ;

for ( ; operators.size( ) > 0 ; )

else

if ( compareret == '<' )

else

if ( compareret == '=' )

} // end for

// 儲存當前遇到操作符,當前操作符還缺少右運算元,要讀完右運算元才能計算。

if ( opt2 != ')' )

lastoperator = opt2 ;

}} // end for

/* 上面的 for 會一面遍歷表示式一面計算,如果可以計算的話。

當遍歷完成後,並不代表整個表示式計算完成了。而會有2種情況:

1.剩餘1個運算子。

2.剩餘2個運算子,且運算子1 小於 運算子2。這種情況,在上面的遍歷過程中是不能進行計算的,所以才會被遺留下來。

到這裡,已經不需要進行優先順序比較了。情況1和情況2,都是迴圈取出最後讀入的操作符進行運算。

*/if ( lastoperator != ')' )

for ( ; operators.size( ) > 0 ; )

return operands[ 0 ] ;

}

Leetcode 逆波蘭表示式求值

解題思路 c 通過乙個棧實現,整體用乙個while迴圈遍歷整個字串,當遇到不能把字元轉換成整型時進行判斷,同時將棧頂兩個元素出棧進行相關運算,運算結果放入棧中繼續進行遍歷。要點 不同資料型別之間的轉換,如果轉換成功則返回true,否則返回false。int.tryparse string s,out...

表示式求值

程式的說明見清華大學出版社 資料結構 c語言版 include include define stack init size 40 define stackincrement 20 define ok 1 define false 0 typedef structs stack typedef st...

表示式求值

既然是表示式求值,自然需要在記憶體中儲存計算結果以及中間值。在 用c語言寫直譯器 一 中提過 變數要求是若型別,而 c 語言中的 view plaincopy to clipboardprint?in basic io.h define memery size 26 typedef enum var...