|

楼主 |
发表于 2023-8-8 15:42
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 shaowu459 于 2023-8-8 16:04 编辑
这个问题仍然可以使用模拟“栈”的方式来解决,只需要在循环过程中同时存储循环的字符和其位置就可以。参考公式如下:
- =IFERROR(REDUCE(A2,DROP(REDUCE(0,ROW($1:99),LAMBDA(x,y,LET(s,MID(A2,y,1),t,VSTACK(HSTACK(s,y),x),SWITCH(s,"(",t,")",IF(@x="(",DROP(x,1),t),x)))),-1,1),LAMBDA(x,y,REPLACE(x,y,1,))),A2)
复制代码
公式主要思路说明如下:
1)由于需要同时记录循环字符的字符本身和其位置,因此REDUCE函数第二参数使用ROW(1:99)这样的数组,LAMBDA循环体中运算时,可以使用MID函数根据第二参数y提取字符,同时y本身又是字符位置。
2)循环的过程中,如果碰到“(”,则将"("和其位置的数组{"(",y}入栈,堆积在x上方。
3)如果碰到")"要分两种情况来看,如果此时栈顶(x左上角的字符)是"("说明这个")"是可以和"("匹配的,此时将x栈顶元素出栈,也即DROP(x,1)去掉x第一行;如果此时栈顶不是"(",说明这个")"是多余的,入栈。
4)碰到其他字符都不做出入栈处理,保留x不变。
5)循环完毕后,x的第一列就是没有被匹配走的"("或")",也就是多余的括号(其中一种情况),x的第二列就是多余的这些括号在原字符串中的位置。
6)循环x的第二列位置,将原字符串对应位置的字符替换成空即可。
|
|