电竞比分网-中国电竞赛事及体育赛事平台

分享

Excel函數(shù)式編程:求右括號位置

 靜謐之家 2024-07-16 發(fā)布于山東

Microsoft 365中增加了很多新函數(shù),使用這些新函數(shù)可以實現(xiàn)其他編程語言中的部分數(shù)據(jù)或數(shù)組操縱技巧,拓展工作表函數(shù)解決問題的新思路。本文通過一個尋找第n個左括號對應(yīng)右括號位置的例子來介紹使用工作表函數(shù)模擬“?!辈僮鞯囊环N方法。

一、什么是“?!?/h3>

棧(stack)又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入?;驂簵?,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。

例如,我們可以把序號堆積入棧,然后當(dāng)符合條件時,從棧頂一個一個移除,相當(dāng)于后進棧的先移出棧。

 

二、Excel工作表函數(shù)模擬入棧和出棧操作

在Excel中,可以使用VSTACK函數(shù)達到增加棧頂元素的目的,例如將數(shù)字5堆積到棧頂:

同樣,利用DROP函數(shù)可以實現(xiàn)移除棧頂元素的目的:

如果當(dāng)前棧里只有一個元素,移除這個元素時會產(chǎn)生錯誤值:

為了避免上述情況的出現(xiàn),我們可以給棧設(shè)置一個初始值,例如0,這樣有進棧元素后再移除不會產(chǎn)生錯誤:

 

三、求括號位置題目描述

下面,我們來正式說這個題目。相關(guān)原數(shù)據(jù)和描述如下圖所示:

簡單說,就是找出字符串中第n個左括號{對應(yīng)的右括號}的位置。

 

四、解題思路分析

因為要模擬棧的操作,所以可以先想想一下這個棧的元素構(gòu)成,為了避免錯誤,給棧一個初始值0,然后棧頂保留待匹配的{編號,棧底保留累計進過棧的{個數(shù)。

然后分幾種情況來處理:
1)當(dāng)字符是{時,將這個{的編號,也即從左到右是第幾個},加入棧頂。例如第一個{入棧時,將1加在棧頂,生成數(shù)組{1;0}。那么怎么知道當(dāng)前這個{是第幾個{呢,因為我們維護的棧最底端會記錄累計入過棧的{數(shù)量,所以要加入棧頂?shù)膡的編號就是棧底的數(shù)字+1。

2)當(dāng)字符是{時還有一步要執(zhí)行,就是將當(dāng)前的{是第幾個加入棧底,也就是將第1步的編號加在數(shù)組最下面。例如第一個{入棧時,將1加在棧頂后,將1也加在棧底,生成數(shù)組{1;0;1}。當(dāng)然,這個步驟,也可以不將編號直接堆積在數(shù)組下面增加數(shù)組長度,可以動態(tài)更新數(shù)組最后一個值為上述編號,例如將原來的初始值更新成1,然后再將1堆積在上面,形成數(shù)組{1;1},但是公式處理會長一些。每次循環(huán)到{的時候,都會這樣操作,記錄累計有多少個{入過棧。

3)當(dāng)字符是}時,這個}肯定是和棧頂編號的{匹配的,因為括號之間不交叉。此時,會分兩種情況:
第一種情況,當(dāng)棧頂?shù)木幪柌坏扔趎時,將棧頂?shù)膡編號做出棧處理,意味著這個編號的{有}匹配了。
第二種情況,當(dāng)棧頂?shù)木幪柕扔趎時,意味著當(dāng)前的}就是和第n個{匹配的},這時,輸出當(dāng)前}的位置即可。

4)當(dāng)字符不是{或},維持棧不變。

舉幾個簡單的例子來說明樓上的解題步驟。

例1:字符串為“{}{a,{b,c}}”,n=1,結(jié)果返回2。

第一個字符是{,因此編號1入棧,棧底也變成1。第二個字符是},此時因為棧頂?shù)木幪柺?,等于n,所以這個}就是和第一個{對應(yīng)的},因此返回當(dāng)前}的位置2。

例2:字符串為“{{}}{{a,b},{b,c}}”,n=2,結(jié)果返回3。

第一個字符是{,因此編號1入棧,數(shù)組變成{1;0;1}。第二個字符是{,因此編號2入棧,數(shù)組變成{2;1;0;1;2}。第3個字符是},此時因為棧頂?shù)木幪柺?,等于n,所以這個}就是和第一個{對應(yīng)的},因此返回當(dāng)前}的位置3。

例3:字符串為“{}{}{{a,b}{c,{d,e}}}”,n=4,結(jié)果返回10。

步驟和前面一樣,只不過當(dāng)棧頂不等于n的時候,就要將棧頂數(shù)字出棧,表示已經(jīng)有}與之匹配了。

 

五、具體公式及簡要說明

有了上面的基礎(chǔ),我們就可以寫出以下公式:

?復(fù)制?復(fù)制?復(fù)制
?復(fù)制
=-REDUCE(0,ROW($1:99),LAMBDA(x,y,IF(@x<0,x,SWITCH(MID(A2,y,1),"{",VSTACK(MAX(x)+1,x,MAX(x)+1),"}",IF(@x=B2,-y,DROP(x,1)),x))))

公式簡要說明如下:

?復(fù)制?復(fù)制
?復(fù)制
=-REDUCE(
0, 棧底初始值設(shè)置為0
ROW($1:99), 每個字符的位置
LAMBDA(x, y,
IF(
@x < 0, 返回結(jié)果位置后,將位置變成負數(shù),判斷如果是負數(shù)就保持x不變。
x,
SWITCH(
MID(A2, y, 1), 遍歷每個字符
"{", VSTACK(MAX(x) + 1, x, MAX(x) + 1), 如果字符是{,棧頂和棧底都增加當(dāng)前{的編號
"}", IF(@x = B2, -y, DROP(x, 1)), 如果字符是},如果棧頂=n,則返回位置的負數(shù)(即-y),否則彈出棧頂元素。
x 如果是其他字符,都保持棧不變。
)
)
)
)

圖文作者:超人

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多