支架平衡


20

您将得到一个(可能为空)字符串,其中包含方括号([{()}])和其他任何字符(A- Za- z0- 9,标点符号)。您需要检查其是否遵循以下规则:

  • 非方括号字符将被忽略。
  • 每个开放式括号[{(都有一个封闭式括号)}]。所以[](是不允许的。
  • 支架正确嵌套。[(])不允许。
  • 弯括号中不能包含方括号。简单括号内不能包含大括号或方括号。因此[({})][{[]}]并且({})是不允许的。括号可以与类似的括号嵌套,因此[[{((()))}{{(())}}]()]{()}是允许的。

根据您的选择,输出是单个真实/错误值。

最短的代码胜出。


测试用例

b[[a{(/)}(())+={{}-}],] ->有效

([h][e][l][l][o]) ->无效

[///[{(\/(arg()))}1{{((-)-2)}}]()]{()} ->有效

hi ->有效



9
@FUZxxl似乎是一个艰巨的挑战。我觉得虽然那里还有另一个骗子。
马丁·恩德

@MartinBüttner是的,可以。我添加了一些测试用例。您是否找到了所要的副本?
ghosts_in_the_code

1
@MartinBüttner:这个挑战可能是您在想的。
Ilmari Karonen

1
我认为我们应该关闭另一个问题,作为对此的重复;这样会更好,因为它的奖金较少。
lirtosiast 2015年

Answers:


5

视网膜,84字节

^([^][}{)(]|()\(|(?<-2>)\)|(?!\2)((){|(?<-4>)}|(?!\4)(()\[|(?<-6>)])))*$(?!\2|\4|\6)

在线尝试。

这是对基本括号进行检查的.NET regex的相当简单的扩展(但经过精心设计)。

尽管使用平衡组完全有可能,但是Perl的递归无疑在这里具有优势。但是,这两种方法都被抛弃了单个正则表达式匹配项的优雅之处,而倾向于通过重复替换逐渐减少输入,就像Digital Trauma的sed答案一样。可以在Retina中以34个字节来实现,但是我很犹豫自己写代码,因为我没有想到。


5

视网膜,34

首先,应归还应付款的信用:

我独立地(后来)在sed中提出了相同的方法,所以我希望通过发布以下内容,我不会踩到任何脚趾(无论是大脚还是其他脚):

[^][(){}]

+`\(\)

+`{}

+`\[]

^$

所以,现在有一个sudo apt-get install mono-completegit clone https://github.com/mbuettner/retina.git我有我的Ubuntu VM工作视网膜。这是测试输出:

$ while read; do echo "Input: \"$REPLY\", Ouput: $( mono Retina.exe -s brbal.ret <<< "$REPLY" )" ; done < ../brbal.txt 
Input: "[[{((()))}{{(())}}]()]{()}", Ouput: 1
Input: "b[[a{(/)}(())+={{}-}],]", Ouput: 1
Input: "[///[{(/(arg()))}1{{((-)-2)}}]()]{()}", Ouput: 1
Input: "hi", Ouput: 1
Input: "", Ouput: 1
Input: "", Ouput: 1
Input: "([h][e][l][l][o])", Ouput: 0
Input: "[](", Ouput: 0
Input: "[(])", Ouput: 0
Input: "[({})]", Ouput: 0
Input: "[{[]}]", Ouput: 0
Input: "({})", Ouput: 0
$ 

@ThomasKwa查看测试输出。我相信代码是正确的,并且所有测试用例都通过了。您在代码中看到了特定的问题,还是您认为会失败的特定测试用例?
Digital Trauma 2015年

@ThomasKwa我没有移植他们的代码,因为我不知道任何ESMIN的功能。我只是根据看起来的样子编写了此代码,所以我认为没有任何理由应该具有相同的错误。
马丁·恩德

哇,@MartinBüttner,您说对了!是的,我认为从内到外递归替换匹配的括号是最合逻辑的。快速调整以适合代码规范使其工作。
Mama Fun Roll 2015年

3

塞德,53岁

s/[^][(){}]//g
:;s/()//;t
:b;s/{}//;tb
:c;s/\[\]//;tc

在这里,我声称由于sed并没有真正的真假概念,因此我将空字符串定义为真,将所有其他字符串定义为假。

如果那是不可接受的,那么我们可以添加几行,因此:

塞德,66

s/[^][(){}]//g
:;s/()//;t
:b;s/{}//;tb
:c;s/\[\]//;tc
/./c0
/^$/c1

这将输出0表示false,1表示true。


请参阅我对Momentmanful对于完全相同的解决方案的Retina版本的回答的评论(34字节;打印01)。我不能说应该由谁发布,但可能应该是你们两个中的一个。
马丁·恩德

3

CJam,27 26字节

"(){}[]"q1$f&_,@2/e*{/s}/!

打印1(真)或0(假)。在线尝试!验证所有测试用例。

怎么运行的

"(){}[]"                    Push that string.
        q                   Read all input and push it on the stack.
         1$                 Copy the bracket string.
           f&               Intersect each input character with the bracket string.
                            This pushes an array of singleton and empty strings.
             _,             Get the length of the array (L), i.e., the number of
                            characters in the original input.
               @            Rotate the bracket string on top of the stack.
                2/          Split it into ["()" "{}" "[]"].
                  e*        Repeat each character pair L times.
                    {  }/   For each character pair.
                     /      Split the string on the stack at occurrences of that
                            character pair. This dosn't work properly the first
                            time, since there's a string array on the stack.
                      s     Flatten the resulting array of strings.
                         !  Apply logical NOT.


2

Japt42 37字节

使用我没有意识到自己的语言的功能节省了5个字节...感谢您添加@Downgoat!

Japt确实需要更好的RegExp支持...

!Uo"()[\\]\{}" e"\\(\\)" e"\{}" e"\\[]

在线尝试!

怎么运行的

               // Implicit: U = input string
Uo"()[\\]\{}"  // Remove all non-bracket.
e"\\(\\)"      // Recursively remove all pairs of simple brackets.
e"\{}"         // Recursively remove all pairs of curly brackets.
e"\\[]         // Recursively remove all pairs of square brackets.
!              // Return the Boolean NOT of the result.
               // (true for empty string, false for anything else)
               // Implicit: output last expression

2

C99,226 208 207字节

这是我第一次尝试打高尔夫球

#define S s[i]
t(s,i)char*s;{int a[]={['[']=0,['{']=0,['(']=0};for(i=0;S*!(S=='{'&a['(']|S=='['&(a['(']|a['{'])|S==']'&(a['(']|a['{'])|S=='}'&a['(']);i++)a[S]++,a[S-S/90-1]--;return !(a['[']+a['{']+a['(']);}

可读性:

int t(char* s){
    int a[265]={['[']=0,['{']=0,['(']=0};
    for(int i=0;s[i]&&!((s[i]=='{'&a['(']>0)|(s[i]=='['&(a['(']>0|a['{']>0))|(s[i]==']'&(a['(']>0|a['{']>0))|(s[i]=='}'&a['(']>0));i++){
        a[s[i]]++;
        a[s[i]-(s[i]/90+1)]--;
    }
    return !(a['[']+a['{']+a['(']);
}

有一个缓冲区溢出,但是似乎没有任何影响-我相信这是由于对齐。


1
您可以忽略char* s
Cyoce

不知道-谢谢
dj0wns

1

Perl,50 + 1 = 51字节

$_=/^((([^][)(}{]|\((?3)*\))|{(?2)*})|\[(?1)*])*$/

要求-p标记并打印1真实性,不打印虚假结果。我指望-p一个,因为它可以与-e

> perl -pe '$_=/^((([^][)(}{]|\((?3)*\))|{(?2)*})|\[(?1)*])*$/'

使用Perl的漂亮的递归正则表达式功能,代码基本上只是针对输入的简单正则表达式匹配。

感谢Dennis帮助我进行了测试,并使Perl样板高尔夫球起来。


1

Python 3:120个字节

@Adnan的答案为基础,事实证明它更易于使用:

import re
x=re.sub('[^[\](){}]','',input())  
for i in('()','{}','[]'):  
 while x.find(i)>=0:x=x.replace(i,'')  
print(x=='')

1

Python 3中,196 170 160 154字节

尴尬的长,感谢Mego节省了6个字节:

d=y=""
for C in input():
 for a in "[](){}":y+=C*(C==a)
 y=y.replace("()",d)
x=y
for r in y:x=x.replace("{}",d)
for s in y:x=x.replace("[]",d)
print(x==d)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.