LeetCode Lisp語法解析(細節處理)

2021-09-20 13:03:01 字數 3784 閱讀 4947

給定乙個類似 lisp 語句的表示式 expression,求出其計算結果。

表示式語法如下所示:

表示式可以為整數,let 語法,add 語法,mult 語法。表示式的結果總是乙個整數。(整數可以是正整數、負整數、0)

let 語法表示為 (let v1 e1 v2 e2 … vn en expr), 其中 let語法總是以字串

"let"來表示,接下來會跟隨乙個或多個交替變數或表示式,也就是說,第乙個變數 v1被分配為表示式 e1 的值,第二個變數 v2

被分配為表示式 e2 的值,以此類推;最終 let 語法的值為 expr表示式的值。

add語法表示為 (add e1 e2),其中 add 語法總是以字串 "add"來表示,該語法總是有兩個表示式e1、e2,

該語法的最終結果是 e1 表示式的值與 e2 表示式的值之和。

mult語法表示為 (mult e1 e2) ,其中 mult 語法總是以字串"mult"表示, 該語法總是有兩個表示式

e1、e2,該語法的最終結果是 e1 表示式的值與 e2 表示式的值之積。

在該題目中,變數的命名以小寫字元開始,之後跟隨0個或多個小寫字元或數字。為了方便,「add」,「let」,「mult"會被定義為"關鍵字」,不會在表示式的變數命名**現。

最後,要說一下範圍的概念。在做計算時,需要注意優先順序,在最內層(根據括號)的表示式的值應該先計算,然後依次計算外層的表示式。我們將保證每乙個測試的表示式都是合法的。有關範圍的更多詳細資訊,請參閱示例。

示例:

輸入: (add 1 2)

輸出: 3

輸入: (mult 3 (add 2 3))

輸出: 15

輸入: (let x 2 (mult x 5))

輸出: 10

輸入: (let x 2 (mult x (let x 3 y 4 (add x y))))

輸出: 14

解釋:

表示式 (add x y), 在獲取 x 值時, 我們應當由最內層依次向外計算, 首先遇到了 x=3, 所以此處的 x 值是 3.

輸入: (let x 3 x 2 x)

輸出: 2

解釋: let 語句中的賦值運算按順序處理即可

輸入: (let x 1 y 2 x (add x y) (add x y))

輸出: 5

解釋:

第乙個 (add x y) 計算結果是 3,並且將此值賦給了 x 。

第二個 (add x y) 計算結果就是 3+2 = 5 。

輸入: (let x 2 (add (let x 3 (let x 4 x)) x))

輸出: 6

解釋:

(let x 4 x) 中的 x 的作用範圍僅在()之內。所以最終做加法操作時,x 的值是 2 。

輸入: (let a1 3 b2 (add a1 1) b2)

輸出: 4

解釋:

變數命名時可以在第乙個小寫字母後跟隨數字.

注意:

我們給定的 expression 表示式都是格式化後的:表示式前後沒有多餘的空格,表示式的不同部分(關鍵字、變數、表示式)之間僅使用乙個空格分割,並且在相鄰括號之間也沒有空格。我們給定的表示式均為合法的且最終結果為整數。

我們給定的表示式長度最多為 2000 (表示式也不會為空,因為那不是乙個合法的表示式)。

最終的結果和中間的計算結果都將是乙個 32 位整數。

思路分析:這道題是典型的字串細節處理問題,我們只要抓住每次處理乙個"(…)",這個expression是會得到乙個值,而只有add、mult、let三種操作。

首先介紹表示式的可能情況:

第一種:表示式是"(...)",按照三種基本操作遞迴處理得到表示式的值。

第二種:表示式是變數,直接返回變數對應的值,比如(let x 2 (add x 5)),let中賦值x = 2,則add(x, y)第乙個引數表示式的值x = 2

第二種:表示式是常量,直接返回常量的值,比如(add 3 5),l則add(x, y)兩個引數表示式都是常量x = 2, y = 3

下面是三種基本操作:

第一種:(add e1 e2),處理add,我們先處理e1、e2兩個表示式,得到e1、e2兩個表示式的值,進行加法計算,得到當前expression的值

第二種:(mult e1 e2),處理mult,我們先處理e1、e2兩個表示式,得到e1、e2兩個表示式的值,進行乘法法計算,得到當前expression的值。

第三種:(let v1 e1 v2 e2 ... vn en expr),對於(v1 e1),(v2,e2),(v3,e3), ... , (v n - 1,e n - 1),(v n,e n)這都是賦值操作,對於e1到en共n個表示式,我們分別求出這n個表示式的值,然後賦值到n個變數v1到vn即可,最後求出表示式expr的值就是當前expression的值。

class

solution

//開始處理以nowindex為起始的乙個expression

intmyevaluate

(string &expression,

int&nowindex, unordered_map

int> hashmap)

else

nowindex +=1

;//跳過空格

//第二步:求add的第二個表示式引數的值

if(expression[nowindex]

=='('

)else

nowindex +=1

;//跳過右括號

return firstnum + secondnum;

//進行加法操作

}else

if(expression[nowindex]

=='m'

)else

nowindex +=1

;//跳過空格

//第二步:求mult的第二個表示式引數的值

if(expression[nowindex]

=='('

)else

nowindex +=1

;//跳過右括號

return firstnum * secondnum;

//進行乘法操作

}else

//下面將會每次處理乙個變數乙個表示式

string str ="";

while

(expression[nowindex]

!=')'

&& expression[nowindex]

!=' ')if

(expression[nowindex]

==')'

)else

}else

else

nowindex +=1

;}}}

}//讀取nowindex為起始下標的乙個表示式(這個表示式是常量比如2,或者是乙個在hashmap中的變數)

這種題目一般都不是很難,就是細節處理需要嚴密的邏輯以及清新的思路。

XML入門精解之結構與語法

現在我們暫且使用 記事本 來建立我們的 xml檔案吧。先看乙個 xml檔案 例1 xml version 1.0 encoding gb2312 參考資料 書籍 名稱 xml入門精解 名稱 作者 張三 作者 貨幣單位 人民幣 20.00 書籍 書籍 名稱 xml 語法 名稱 此書即將出版 作者 李四...

隨意細解 OC 屬性 點語法 KVC

利用屬性宣告set get方法。學習階段,使用mrc,並在 m 檔案中練習get set方法的完整實現。注意 建立工程 預設是arc狀態 自動管理記憶體 在工程的設定中,將objective c automatic reference counting 的 yes 改為 no,手動管理記憶體 mrc...

閉式解 解析解

閉式解也被稱為解析解,是通過嚴格的公式所求得的解,即包含分式 三角函式 指數 對數甚至無限級數等基本函式的解的形式。通過給出解的具體函式形式,從解的表示式中就可以算出任何對應值。解析解,又稱為閉式解,是可以用解析表示式來表達的解。在數學上,如果乙個方程或者方程組存在的某些解,是由有限次常見運算的組合...