ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 401|回复: 8

[分享] 365新函数:移除最少无效的括号-“栈”+循环调试

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-8-8 15:29 | 显示全部楼层 |阅读模式
本帖最后由 shaowu459 于 2023-8-8 16:14 编辑

已知:
A列字符串只包括小写英文字母和"("、")"。有效的括号指:左括号必须用右括号闭合,左括号必须以正确的顺序闭合。

要求:
删除A列字符串中的最少数目的"("或")",使剩余字符串中的括号为有效括号。结果返回空字符串、不包含括号的字符串、原字符串都是可能的结果。结果可能不唯一,示例结果供参考。
图片.png

移除最少无效的括号(参考公式).rar

13.9 KB, 下载次数: 9

评分

3

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-8 15:42 | 显示全部楼层
本帖最后由 shaowu459 于 2023-8-8 16:04 编辑

这个问题仍然可以使用模拟“栈”的方式来解决,只需要在循环过程中同时存储循环的字符和其位置就可以。参考公式如下:
  1. =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)
复制代码
图片.png


公式主要思路说明如下:
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的第二列位置,将原字符串对应位置的字符替换成空即可。

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-8 16:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 shaowu459 于 2023-8-8 16:12 编辑

下面以“su(p(e)r)ma)n”为例子来具体说明。在测试REDUCE函数时,可以通过逐个增加第二参数循环值来查看每次循环的结果。例如首次可以使用ROW(1:1),第二次可以使用ROW(1:2)等。

首先来看内层REDUCE函数的运算过程:
  1. =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))))
复制代码
当y=1时,第一个字符是“s”,保持x初始值0不变:
图片.png

当y=2时,第二个字符是“u”,保持x=0不变:
图片.png

当y=3时,第三个字符是“(”,将左括号和对应位置3堆积在x上方:
图片.png

当y=4时,第4个字符是“p”,保持x不变:
图片.png

当y=5时,第5个字符是“(”,左括号和对应位置入栈:
图片.png

当y=6时,第6个字符是“e”,保持x不变:
图片.png

当y=7时,第7个字符是“)”,因为栈顶字符是“(”,所以匹配出栈,去掉x第一行:
图片.png

当y=8时,第8个字符是“r”,保持x不变:
图片.png


当y=9时,第9个字符是“)”,因为栈顶字符是“(”,所以匹配出栈,去掉x第一行:
图片.png

后面以此类推,循环完毕后,x剩余结果如下:
图片.png

x中除了0外,只有一个“)”和对应的位置12,也就意味着A2单元格的第12个字符“)”没有左括号去正确匹配,因此需要删除。

DROP(数组,-1,1)将得到所有需要剔除字符的位置,然后使用REDUCE函数循环从A2单元格中替换成空即可。

当原字符串中没有括号,或者括号均为有效匹配,最后x中则只剩余{0,#N/A}这个数组,使用REDUCE函数替换时会出错,使用IFERROR函数将错误值处理为原字符串即可。
图片.png

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-8 16:10 | 显示全部楼层
本帖最后由 shaowu459 于 2023-8-8 16:21 编辑

简单总结:
1)使用REDUCE函数的x可以模拟“栈”的操作,如果需要存储字符本身及其位置或其他属性,可以使用VSTACK函数或者HSTACK函数等将其组成数组,根据后续取数方便的需要,堆叠在x上方、下方或者左侧、右侧等。
2)在调试REDUCE函数,观察每步运算结果时,一种常用的方法是将第二参数从循环1次开始,控制每次循环次数+1,这样可以看到每次循环后的结果。如果发现循环次数+1后出错,也方便查找问题产生的原因。

=IFERROR(
    REDUCE(
        A2,
        DROP(
            REDUCE(
                0,
                ROW($1:99),    设定循环次数,代表字符位置,因为空文本不影响,所以可以设置多一些次数
                LAMBDA(x, y,
                    LET(
                        s, MID(A2, y, 1),   遍历每个字符
                        t, VSTACK(HSTACK(s, y), x),    将字符及其位置组成的数组堆积在x上方
                        SWITCH(s, "(", t, ")", IF(@x = "(", DROP(x, 1), t), x)   根据当前字符采取入栈、出栈、保留x不变等处理
                    )
                )
            ),
            -1,
            1
        ),
        LAMBDA(x, y, REPLACE(x, y, 1, ))    循环将无效的(和)所在位置替换成空。
    ),
    A2
)

TA的精华主题

TA的得分主题

发表于 2023-8-8 16:27 | 显示全部楼层
感谢楼主分享,请问过程中用到的函数分析图是什么东东实现的?

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-8 16:29 | 显示全部楼层
橒♂蝣 发表于 2023-8-8 16:27
感谢楼主分享,请问过程中用到的函数分析图是什么东东实现的?

2楼的图还是3楼的图啊?如果是3楼的图,那个是改一个参数,截一个图弄的。2楼的那个是excel里的一个加载项,Excel Labs。

TA的精华主题

TA的得分主题

发表于 2023-8-8 16:45 | 显示全部楼层
shaowu459 发表于 2023-8-8 16:29
2楼的图还是3楼的图啊?如果是3楼的图,那个是改一个参数,截一个图弄的。2楼的那个是excel里的一个加载 ...

感谢楼主,就是2楼这个觉得很有用

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-8-8 16:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
橒♂蝣 发表于 2023-8-8 16:45
感谢楼主,就是2楼这个觉得很有用

嗯,还挺方便的,公式、自定义名称都能看,自动格式化,可以直接复制出来,方便写注释或者阅读。

TA的精华主题

TA的得分主题

发表于 2023-8-8 17:23 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-10 22:16 , Processed in 0.048819 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表