对ACM仰慕已久,无奈今天才开始。好吧,遇到的第二个题目就把我难到了。(实话是第一个)

  进入正题,下面Copy出题目:

  

 现在,有一行括号序列,请你检查这行括号是否配对。
输入
第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
样例输入
3
[(])
(])
([[]()])
样例输出
No
No
Yes 拿到该题目的时候,想的最多的当然是括号匹配的问题,并没有思考其他的。以下是我思考的过程:
随便写一个很长的括号匹配的例子来找到其中的规律。如下:
[([()])()] 欣喜若狂,找到了如下的规律:
======================================================================================================
1.如果这个字符串的长度为奇数,不用看了,这个字符串已经不可能匹配了。所以会用到strlen()函数。
2.对于满足偶数条件的,那就从第一个字符开始查找。先找第一个,再找第二个:
  若第一个和第二个不匹配,表明从最后一个括号肯定是匹配的,所以开始匹配判断。(以此类推)。
====================================================================================================== 当深入分析的时候,发现,好吧,该模型太理想化了,不行。存在严重的错误,只有当该括号完全中心轴对称才会满足这种情况,PASS。 所以,我又想了一下其他的,终于,考虑到递归+消除的思想,想到了一个绝佳的点子:
=======================================================================================================
1.递归-->解析到最小解;
2.消除-->匹配以后我就不用管了。
=========================================================================== 在括号匹配中,总会有这种情况出现:()或[]。当把这一部分消除以后,剩下的部分也总是会出现()或[]。
那么,是否可以将此作为一个单位消除掉,直到最后整个序列全部消除?我想应该是可以的。
但是,如何去实现这一部分?采用什么方式去实现,又是一个头疼的问题。
这让我联想到了播放音乐时候的“节奏条”(姑且这么称呼吧),可以大,可以小,最后可以没有。
所以,我需要两个部分。
1.字符串首地址指针。
2.移动指针。
总觉得少了一点什么,怎么去表示删除的字符呢?在原字符串中可以表示吗?又是一个难题。需要去解决,于是想到了其他的解决方案:
将字符串序列中的第一位开始,一个一个判断,利用"FILO"的方式进行表示,所以就有了如下的思路: ==================================================================================================
1.将元素一个一个压栈,若将要入栈的元素和栈顶元素匹配,那么弹出栈顶元素。
2.遍历整个字符串,当遍历完了以后,判断当前栈底,栈顶都在哪里。如果相等,说明匹配,否则。
=======================================================================
为什么要遍历完?这是一个问题!!为什么不能再中途引进错误判断机制呢?所以,就有了如下的思考:
将这些匹配元素,我们可以分为两类:
一类为左,一类为右。(这不是废话吗?)
书面一点:一类为起始符,一类为结束符
规则是这样的: ================================================
有了起始符,才会出现结束符!
================================================ 但检测到将入栈的元素和栈顶元素不为同一类,并且不匹配。那么,我们就有权去说:不用查了,这个字符串打死我,我也会说No. 如果说,栈操作深奥了,可以利用外部数组(就是数组)的方式来作为删除元素的缓存Buff。 那么,就有了如下的思考:
===============================================================================================
1.判断当前字符串的长度。
2.将字符串从第一个字符拷贝到Buff中。
3.错误判断机制,若在不同类,并且匹配,那么将当前所在的索引处的值初始化,并将数组元素的动态索引值-1.
4.期间,没有错误,并且处理完当前字符串,否则No.
5.ok,没有问题,返回YES。
=====================================================================================
以上,只是解决了字符串的匹配问题,还有输出呈现问题。
输出呈现,是全部遍历完成字符串数组以后,然后再输出的,所以需要有一个缓存Buff,存储当前结果是YES or No。
===============================================================
最简单的,就算是用for循环遍历这个数组了,0为No,1为YES.
=============================================================== 好的,已经解决了提设的问题,但是,想想该问题还是简单化了!
=====================================================================================
  1. 如果是3对匹配,4对匹配呢?
  2. 是否需要考虑封装的问题?将匹配函数封装,满足支持动态扩展的形式进行扩展,而不是固定匹配()和[].
  3. 如果中间存在其他值,而不是单独的字符,该如何处理?忽略掉非匹配字符类?然后按照类似的方法进行。
  4. …………其他
=================================================================================================

以上,便是思考的全部过程,有错误,有修正,觉得对思考有帮助,便记录下来。

以下便是代码了,相信0基础的童鞋应该都可以看懂吧。

 #include <stdio.h>
#include <string.h> int Judge_Sts(char* str,int length);
int Judge_Type(char Name);
int Match_Char(char Start,char End); int main(void)
{
/*局部变量定义*/
int Num;
int Index;
int Str_Length;
char Temp[];
char OutFlag[];
char bflag;
/* 获取行数 */
scanf("%d",&Num);
/* 循环处理 */
for(Index = ;Index < Num; Index++)
{
scanf("%s",&Temp);
/* 判断长度 */
Str_Length = strlen(Temp);
/* 奇数 */
if(Str_Length&)
{
OutFlag[Index] = ;
}
else
{
/* 偶数就开始判断 */
OutFlag[Index] = Judge_Sts(Temp,Str_Length);
}
}
/* 输出YES or NO */
for(Index = ; Index < Num; Index++)
{
if(OutFlag[Index])
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
} /* 判断字符串 */
/*
* 不匹配:0
* 匹配:1
*/
int Judge_Sts(char* str,int length)
{
int i;
char* TagStr = NULL;
int Bret = ;
char Temp;
int Str_Top = ; TagStr = str;
for(i = ; i < length; i++)
{
Temp = *(str+i);
if(Judge_Type(Temp))
{
if(Str_Top == )
{
Bret = ;
break;
}
else
{
Str_Top--;
if(Match_Char(*(TagStr+Str_Top),Temp))
{
;
}
else
{
Bret = ;
break;
}
}
}
else
{
*(TagStr+Str_Top) = *(str+i);
Str_Top++;
}
} if(Str_Top)
{
Bret = ;
}
else
{
Bret &= ;
}
return (Bret);
} /* 判断该字符属于哪一种,开始字符 or 结束字符 */
/*
* 开始符:0
* 结束符:1
*/
int Judge_Type(char Name)
{
int bRet = ;//默认需要和前一个判断
switch(Name)
{
case '(':
case '[':
bRet = ;
break;
case ')':
case ']':
bRet = ;
break;
default:
break;
} return (bRet);
} /* 判断是否匹配 */
int Match_Char(char Start,char End)
{
int a;
if((Start == '(' && End == ')') || (Start == '[' && End == ']') )
{
a = ;
}
else
{
a = ;
}
return a;
}

(PS:有时间在想出一些巧妙的方法出来吧。先这样了。)

ACM-括号匹配问题的更多相关文章

  1. 南阳理工ACM 括号匹配问题,并求出使得括号能够匹配需要新增的最小括号数(括号匹配(二))

    描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起 ...

  2. [原]NYOJ 括号匹配系列2,5

    本文出自:http://blog.csdn.net/svitter 括号匹配一:http://acm.nyist.net/JudgeOnline/problem.php?pid=2 括号匹配二:htt ...

  3. 2018 Multi-University Training Contest 1-1002 -Balanced Sequence(括号匹配+贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6299 题目: 题意:t组数据,每组数据给你一个n表示给你n个括号串,这n个括号串之间进行组合,求能够匹 ...

  4. 括号匹配 区间DP (经典)

    描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来 ...

  5. YTU 3003: 括号匹配(栈和队列)

    3003: 括号匹配(栈和队列) 时间限制: 1 Sec  内存限制: 128 MB 提交: 2  解决: 2 [提交][状态][讨论版] 题目描述 假设一个表达式中只允许包含三种括号:圆括号&quo ...

  6. POJ C程序设计进阶 编程题#4:括号匹配问题

    编程题#4:扩号匹配问题 来源: POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 在某 ...

  7. 【栈思想、DP】NYOJ-15 括号匹配(二)

    括号匹配(二) 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能 ...

  8. NYOJ 题目15 括号匹配(二)(区间DP)

    点我看题目 题意 : 中文题不详述. 思路 : 本来以为只是个小模拟,没想到是个区间DP,还是对DP不了解. DP[i][j]代表着从字符串 i 位置到 j 位置需要的最小括号匹配. 所以初始化的DP ...

  9. C语言数据结构之栈:括号匹配

    括号匹配这是个很简单的题目,如果只有小括号,就模拟进栈和出栈的过程就行了: 注:输入时'@'作为结束标志 #include <stdio.h> int main() { freopen(& ...

  10. [NYOJ 15] 括号匹配(二)

    括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 给你一个字符串,里面只包含"(",")","[&qu ...

随机推荐

  1. IBatis学习

    (1)建立 SqlMap.config文件 <?xml version="1.0" encoding="utf-8" ?> <sqlMapCo ...

  2. FCC上的初级算法题

    核心提示:FCC的算法题一共16道.跟之前简单到令人发指的基础题目相比,难度是上了一个台阶.主要涉及初步的字符串,数组等运算.仍然属于基础的基础,官方网站给出的建议完成时间为50小时,超出了之前所有非 ...

  3. PHP数组处理函数的使用array_map(三)

    /*函数array_map()函数:多数组回调函数---将回调函数作用到给定数组的单元上 * 1.语法:array array_map ( callback callback, array arr1 ...

  4. 命名不规范引发的DropDownListFor无法选中

    问题的引出: 项目中遇到和以下链接相同的问题,大概可以描述为:后台ViewData["KeyName"],前台Model属性里也有一个字段KeyName,那么DropDownLis ...

  5. Autolayout学习(1)-了解Autoreszing

    1. 为什么要有Autoreszing? 在Xcode6之前,如果定义了下面的一个布局,同时运行在不同尺寸设备下会显示不同的效果. (iPhone6-4.7inch) (iPhone5s-4inch) ...

  6. Javabean+servlet+JSP(html)实例应用

    大家都知道Javabean+servlet+JSP是最简单的MVC模式.的确,在一个小型的项目中,这个模式完全够用. 它优雅并且简洁.加上jQueryui的完美展示效果,让这个模式看起来非常合适.当然 ...

  7. 卸载金山猎豹免费WIfi后,上不了网的解决办法

    进入网络和共享中心,打开网络适配器,右键无线连接,属性,就在打开属性的那个页面,在靠上的位置有个LieBao xxx Driver,卸载. 然后,打开浏览器,试试这个链接:www.baidu.com. ...

  8. Spring Data JPA 的配置文件 已经数据库的状态

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. JavaScript 学习笔记 -- String.trim + format

    最近仍在IE6徘徊,低版本的浏览器没有实现JavaScript 的trim() 和 format(). . 主要是这两个使用的比较多,先整理出来: 1.trim() -- 去除字符串中开始和结尾部分, ...

  10. JS禁止WEB页面鼠标事件大全

    <!--禁止鼠标右键代码-->:<noscript><ifra:<scriptlanguage=javas:<!--:if(window.Event):doc ...