ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 最长有效括号

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-1-5 17:40 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。


输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"


'-------------------------------------------------------





Sub Solution()
    Dim s As String
    s = ")()(()))"
    MsgBox longestValidParentheses(s)
End Sub


Function longestValidParentheses(s As String) As Integer
    Dim ans, n, i, l, r
    ans = 0: n = Len(s)
    If n = 0 Then longestValidParentheses = 0: Exit Function

    l = 0: r = 0
    For i = 1 To n
        If Mid(s, i, 1) = "(" Then
            l = l + 1
        Else
            r = r + 1
        End If
        If l = r Then
            ans = Application.Max(ans, 2 * r)
        Else
            If r > l Then
                l = 0: r = 0
            End If
        End If
    Next

    l = 0: r = 0
    For i = n To 1 Step -1
        If Mid(s, i, 1) = "(" Then
            l = l + 1
        Else
            r = r + 1
        End If
        If l = r Then
            ans = Application.Max(ans, 2 * r)
        Else
            If l > r Then
                l = 0: r = 0
            End If
        End If
    Next

    longestValidParentheses = ans
End Function


请问:怎么证明该方法是正确的?
谢谢!

TA的精华主题

TA的得分主题

发表于 2024-1-6 04:48 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
最近正好在学正则平衡组,只有php、perl、c#支持这样的写法,可以递归的匹配配对的左右括号,不知道有没有帮助
image.png

TA的精华主题

TA的得分主题

发表于 2024-1-6 11:41 | 显示全部楼层
这个对不对?
  1. Sub test()
  2. s = ")(()(()))("
  3. 1:
  4. For i = 1 To Len(s)
  5.     If Mid(s, i, 1) = "(" Then
  6.         n = i
  7.     ElseIf Mid(s, i, 1) = ")" Then
  8.         If n > 0 Then
  9.             m = m + 2
  10.             Mid(s, n) = "|"
  11.             Mid(s, i) = "|"
  12.             n = 0
  13.             GoTo 1
  14.         End If
  15.     End If
  16. Next
  17. MsgBox m
  18. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2024-1-6 13:01 | 显示全部楼层
没看懂,是这个意思吗
  1. UBound(Split(s, "()")) * 2
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-7 11:48 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
wanghan519 发表于 2024-1-6 04:48
最近正好在学正则平衡组,只有php、perl、c#支持这样的写法,可以递归的匹配配对的左右括号,不知道有没有 ...

谢谢 wanghan519 !
如果要有学正则的,应该会有帮助的。我不大会正则

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-7 11:50 | 显示全部楼层

谢谢 半百 !
3楼是暴力的思路:每次从头到尾,先找左再找右,并把找到的两个位置上的字符,替换为指定字符。


因为只是括号对的计数,没判断 格式正确且连续,
所以会有这种错误,s = ")(())(()" ,返回是4,不是6。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-7 11:56 | 显示全部楼层
cidanji 发表于 2024-1-6 13:01
没看懂,是这个意思吗

谢谢 cidanji !
题意大致如1楼所说

TA的精华主题

TA的得分主题

发表于 2024-1-7 12:12 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
这个题目好像超人版主就玩过了,上个月拿出来用365函数搞,那些大佬可厉害了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-8 09:43 | 显示全部楼层
jiangxiaoyun 发表于 2024-1-7 12:12
这个题目好像超人版主就玩过了,上个月拿出来用365函数搞,那些大佬可厉害了。

发这贴的目的是,是想解释1楼方法为什么会是对的,
比如,为什么非要正反各遍历一次?


如果s本身是有效的,无论正反,遍历一次即可。比如 s = "(()())"
...........无....,必须正反各遍历一次才行。比如 s =  ,,,,,,,,,还在想例子


就像看魔术,明知道有一个原因,就是一下子说不上来

TA的精华主题

TA的得分主题

发表于 2024-1-8 11:05 | 显示全部楼层
爱疯 发表于 2024-1-8 09:43
发这贴的目的是,是想解释1楼方法为什么会是对的,
比如,为什么非要正反各遍历一次?

从前向后好像找不到这个
()((()())
从后向前找不到这个
(()()))()

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-19 11:33 , Processed in 0.048460 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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