使用正则表达式解决平衡括号问题


圆括号问题

由于这是一个著名的编程问题,因此我们大多数人有可能在CS101课程或其他课程中解决了这个问题。 尽管如此,我仍然坚持我们在浏览下一部分之前先浏览一下问题陈述。

假设我们有一个只能包含方括号[],括号()和大括号{}输入字符串 。 然后,当我们的输入字符串满足两个条件时,它被认为是平衡的:

  • LOFC( 最后打开的是第一个关闭的 )意味着最后打开的是第一个关闭的。
  • LOFC考虑到开括号和闭括号属于同一对,即(),[]和{}

此外, 如果输入字符串为空,则可以说它是balance

样本输入数据

接下来,让我们看一些示例输入字符串,并找出它们是否平衡:

[()[]{}]{} is balanced
[ ][ ]() is balanced
() is balanced
))(( is not balanced
{) is not balanced

偏见的头脑留有很小的空间

是的,我知道我们中有些人已经创建了堆栈的心理图景来开始解决此问题。

但是,这是您之前解决过的一件好事,或者您是第一次阅读此问题,并很快想到了基于堆栈的解决方案。 但是,我敦促您暂时释放空间 ,以免您的想法出现偏差。

使用顶空的解决方案

用正则表达式解决它的全部目的在于,如我们所见,编码更加直观 。 此外,就算法的时间复杂度而言,我绝对不是一个更好的方法!

首先,让我们重新回顾上一节中示例输入列表中的第一个:

[()[]{}]{}

现在,让我们尝试在解决问题观察自己的想法 。 我们可以是一个天才,可以快速解决它,但是我们需要慢慢观察这个思考过程。 此外,我们应该牢记一切。 这意味着我们必须避免使用笔和纸。

尽管我们不需要超过3分钟 ,但我们可以花尽可能多的时间来满意地完成此活动。

除非我们在这里花一些时间,否则没有任何进一步的意义。 没有人会判断我们是否慢–越慢越好,但是我们必须全神贯注于这项活动,才能一次完成。

而且,只要我们准备就绪,就让我们尝试回答一些问题:

  • 我们一口气解决了吗?
  • 我们是否可以专注于字符串中的(),{}和[]之类的模式?
  • 发现平衡模式(),{},[]时我们做了什么?

让我们为给我们一个宽敞的顶部空间以可视化地解决它的整个过程而振奋精神。

现在,每个人都可以以不同的方式想象到这一点。 现在,让我提出如何形象化它。

首先,我很快就能在较宽的方括号内发现(),[],{}的三种模式,以及在最右侧的{}模式。 但是,必须指出的是,我实际上并没有看到包含三个平衡括号的更宽的括号。

然后,一旦我发现了一些平衡的模式,我便试图通过忽略视线中已经发现的模式来集中注意力。 结果,我可以看到[]的一种模式包含了较早观察到的模式。

接下来,我知道没有更多的新模式可以识别了,如果我忽略所有这些模式,那么除了空字符串之外,我什么也没有。

当然,在迈向下一步时,我必须更加集中精力。

就像他们说的那样,一张图片值一千个字,因此我稍后尝试勾画此活动,以更好地描述整个过程:


使用sed实现

啊! 我知道。 我知道。 执行使我们很多人兴奋,

我们,开发人员喜欢行动。 看到实际的代码使我们感到振奋。 是不是

但是, sed
真的吗? 不是Java,Python,Kotlin,Go,Haskell。 连C都没有?

是的,sed,是的。 🙂

sed 是用于模式匹配的出色工具 。 实际上,这是一种图灵完整的编程语言 。 所以,为什么不呢!

无论如何,我们都遵循顶空方法,而sed将使我们很容易以代码形式形式化关于模式的思想:

:combine
s/ \( \) //g
s/ \{ \} //g
s/ \[ \] //g
t combine

s/^$/balanced/p
t
s/.*/Unbalanced/p

从字面上看,这就是我们所有的代码。 而且, 它适用于输入流,而不仅适用于单个string 。 这不是很好吗?

尽管我喜欢这个简单的解决方案,但我也同意,如果您不熟悉sed,那么这些内容可能会让您有些不知所措。 所以,让我为您总结一下。

因此, 我们的脚本使用了简单循环和使用regex进行替换的概念 。 对于替换,它使用s的s替换函数和全局标志g来在所有情况下应用效果:

s /regex/ replacement /g

此外,我们继续进行模式匹配和替换,直到找不到这三种模式中的任何一种。 我们使用t函数test保持循环:

t label

为此,我们之前使用 (label)函数 定义了称为 Combine 标签

: label

我们必须注意,如果最后一次替换成功,则测试函数t会分支到标签,否则流程将逐行继续。

一旦退出循环,对于平衡的情况我们将有一个空字符串,对于不平衡的情况我们将有一个非空字符串。

结果,我们再次将s替换功能与print, p标志一起使用,以显示一条消息,指出“已平衡”或“不平衡”。

但是,等等,在倒数第二行,我们没有使用任何标签使用t函数来进行条件分支:

t

没有标签,测试功能将重新开始输入流中下一行的执行周期。 当脚本中的所有命令在当前循环中完成执行时,也会发生这种情况。

现在,让我们进行一次信念飞跃,并使用一些示例输入字符串进行测试。

我们的代码有效吗?

首先,让我们看一下输入字符串:

% nl input_parantheses.txt
     1 [()[]{}]{}
     2 [][]()
     3 ()
     4 ))((
     5 {)
     6 (()())
     7 ))
     8 ()
     9 )()(

最后,让我们执行脚本并查看我们的工作成果:

% sed -E -n -f balanced_parantheses.sed input_parantheses.txt | nl
     1 balanced
     2 balanced
     3 balanced
     4 Unbalanced
     5 Unbalanced
     6 balanced
     7 Unbalanced
     8 balanced
     9 Unbalanced

叹! 我们可以看到输入的每一行的输出都符合预期的结果。

结论

在本教程中,我们依靠直觉和顶空来为圆括号的问题提供足够好的解决方案 。 另外,在sed中实现解决方案时,我们品尝了一些基本的正则表达式。

参考文献

From: https://hackernoon.com/solving-balanced-parentheses-problem-using-regular-expressions-q82w3y4u

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值