花括号的匹配。从逻辑上看,分几种形式:
{ { { }}}
{ {} {} }
{} {} {}
以上3种都是匹配的。所以逻辑处理的时候要考虑这些情况。
简单说一下判断逻辑:
- 遇到
{
的时候,检查一下之前是否有过}
,如果有就要去消掉对应记录;如果}
数量大于{
了,说明必然匹配失败了,直接不需要检查后面的结束匹配验证;如果之前没有出现过}
,那就直接统计。 - 如果遇到
}
就直接统计就好了,不用做什么处理,并且此后就不能继续统计{
了,直到}
的记录全被消掉才可以。
给出一个通用的实现方案:
// 通用实现方案,匹配花括号。(输入与匹配的逻辑分离。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEFT '{'
#define RIGHT '}'
int match(int a, int b)
{
return a == b;
}
void check(char *str)
{
int len = strlen(str);
int ch;
int f = 0, s = 0;
int stopLeftcollect = 0;
int earlyFail = 0;
for (int i = 0; i < len; ++i)
{
ch = str[i];
if (LEFT == ch)
{
if (s > 0)
{
if (s <= f)
{
f = 1 + (f - s);
stopLeftcollect = 0;
s = 0;
}
else
{
printf("======= current line braces match FAIL#\n");
earlyFail = 1;
break;
}
}
else
{
if (!stopLeftcollect)
{
f++;
}
}
}
else if (RIGHT == ch)
{
stopLeftcollect = 1;
s++;
}
}
if (!earlyFail)
{
if (f == s)
{
printf("======= #current line braces match ok\n");
}
else
{
printf("======= #current line braces match FAIL#\n");
}
}
}
int main(int argc, char *argv[])
{
char str[1000];
while (gets(str) != NULL)
{
printf("origin: %s\n", str);
check(str);
}
return 0;
}
==== 通用的方案当然好,但是因为不知道用户的输入程度,直接申请了长度为1000的数组,这样容易造成内存的浪费。
那么,如果直接去一个字符一个字符的判断,就不用申请一个大的数组了。只是,这样也是有利有弊。弊端就是这样的处理逻辑无法通用,只能用于处理控制台输入的,输入与匹配的逻辑耦合在一起了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEFT '{'
#define RIGHT '}'
int match(int a, int b)
{
return a == b;
}
void checkBraces()
{
int ch;
int f = 0, s = 0;
int stopLeftcollect = 0;
int earlyFail = 0;
// 两种情况,一种: {a{b{c}d}e}
// 这种的处理方式就很简单,就是遇到第一个 } 就停止对{ 进行计数,并开始对 } 进行计数,结束后比较二者数量即可。
// 两种情况,二种: {s}{w}{k}
// 这种需要在第二个 { 的时候就比较前一次 的 {,}的数量然后清空计数再次分别统计。
while ((ch = getchar()) != EOF && ch != '\n')
{
if (LEFT == ch)
{
if (s > 0)
{
if (s <= f)
{
f = 1 + (f - s);
stopLeftcollect = 0;
s = 0;
}
else
{
printf("======= current line braces match FAIL#\n");
earlyFail = 1;
break;
}
}
else
{
if (!stopLeftcollect)
{
f++;
}
}
}
else if (RIGHT == ch)
{
stopLeftcollect = 1;
s++;
}
// putchar(ch);
}
printf("EXIT WHILE $$$$$$.\n");
if (!earlyFail)
{
if (f == s)
{
printf("======= #current line braces match ok\n");
}
else
{
printf("======= #current line braces match FAIL#\n");
}
}
while (earlyFail && (ch = getchar()) != '\n')
{
;
}
if (ch == '\n')
{
printf("NEXT LINES\n");
checkBraces();
}
else
{
printf("who you are? %c\n", ch);
// logic error.
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
printf("check match of braces. INPUT:\n");
checkBraces();
return 0;
}
执行效果如下:
{}
origin: {}
======= #current line braces match ok
{}{}
origin: {}{}
======= #current line braces match ok
{{},{}cc{}}
origin: {{},{}cc{}}
======= #current line braces match ok
{}}
origin: {}}
======= #current line braces match FAIL#
{{x},{wq}}
origin: {{x},{wq}}
======= #current line braces match ok