括号匹配问题
前言
- 周一是我女朋友的生日,无奈公司的接口需要我去调试,心里也确实放不下公司的事情,结果周末两天都在公司调试加班,今天周一我和女友都上班,唉,太感谢我女友了,一个男人的高度很大程度上取决于身边的女人啊,祝我宝贝璐璐生日快乐。
- 我的博客都会根据自己的学习水平实时的进行更新,看到有些人转载我的博客没标明出处很上火,而且全是无脑照抄,真是无力吐嘈,感觉用链栈实现括号匹配反而复杂了,用顺序栈即可,重写了ac代码,贴出来跟大家共享
题目
题目描述: 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注. 输入: 输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。 注意:cin.getline(str,100)最多只能输入99个字符! 输出: 对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配。 样例输入: )(rttyy())sss)( 样例输出: )(rttyy())sss)( ? ?$
算法思想:
括号匹配是典型的栈的应用,思路如下:
- 因为题目要求找出不匹配的左、右括号,因此需要两次遍历输入的字符串
- 第一次(从左向右遍历字符串),
- 是左括号,则入栈,同时标记数组的相应位置置空格
- 是右括号,则检测栈是否为空,不为空,则判断有对应的左括号,左括号出栈,标记数组相应位置置空格;为空,则没有对应的左括号,标记数组置‘?’
- 其它字母,标记数组的相应位置置空格
- 第二次(从右向左遍历字符串),
- 是右括号,则入栈
- 是左括号,则检测栈是否为空,不为空,则判断有对应的右括号,同时出栈;为空,则没有对应的左括号,标记数组置‘$’
AC代码:
顺序栈:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define max 101 struct bracket { char data[max]; int top; }; int main() { char str[max], flag[max]; int i, len; struct bracket *leftbracket, *rightbracket; while(scanf("%s", str) != EOF) { //初始化栈 leftbracket = (struct bracket *)malloc(sizeof(struct bracket)); rightbracket = (struct bracket *)malloc(sizeof(struct bracket)); leftbracket->top = rightbracket->top = 0; len = strlen(str); //从左向右检测左括号是否匹配 for(i = 0; i < len; i ++) { switch(str[i]) { case '(' : leftbracket->data[leftbracket->top ++] = str[i]; flag[i] = ' '; break; case ')' : if(leftbracket->top > 0) { flag[i] = ' '; leftbracket->top -= 1; }else { flag[i] = '?'; } break; default : flag[i] = ' '; break; } } //从右向左检测左括号是否匹配 for(i = len - 1; i >= 0; i --) { switch(str[i]) { case ')' : rightbracket->data[rightbracket->top ++] = str[i]; break; case '(' : if(rightbracket->top > 0) { rightbracket->top -= 1; }else { flag[i] = '$'; } break; default : break; } } //打印输出 printf("%s\n%s\n", str, flag); //初始化数组 memset(str, '\0', sizeof(str)); memset(flag, '\0', sizeof(flag)); } return 0; }
链栈:
#include <stdio.h> #include <stdlib.h> #include <string.h> //采用链栈的数据结构 struct stacknode { char bracket; struct stacknode *next; }; typedef struct { struct stacknode *top; }linkstack; /** * Description:初始化链栈 */ void initstack(linkstack *s) { s -> top = NULL; } /** * Description;判断栈是否为空 */ int stackempty(linkstack *s) { int flag; flag = (s -> top == NULL)? 1 : 0; return flag; } /** * Description:入栈操作 */ void push(linkstack *s, char str) { struct stacknode *p; p = malloc(sizeof(struct stacknode)); p -> bracket = str; p -> next = s -> top; s -> top = p; } /** * Description:出栈操作 */ char pop(linkstack *s) { char str; struct stacknode *p = s -> top; str = p -> bracket; s -> top = p -> next; free(p); return str; } int main() { char input[101]; char flag[101]; char ch; int i, len, j, k; linkstack *s; s = malloc(sizeof(linkstack)); while(scanf("%s",input) != EOF) { len = strlen(input); initstack(s); for(i = 0; i < len; i ++) { switch(input[i]) { case '(': //左括号入栈 push(s,input[i]); flag[i] = ' '; break; case ')': //判断栈空 if(stackempty(s)) { flag[i] = '?'; }else { flag[i] = ' '; ch = pop(s); } break; default: flag[i] = ' '; break; } } initstack(s); for(i = len - 1; i >= 0; i --) { switch(input[i]) { case ')': //右括号入栈 push(s,input[i]); break; case '(': //判断栈空 if(stackempty(s)) { flag[i] = '$'; }else { flag[i] = ' '; ch = pop(s); } break; default: break; } } //打印输出 printf("%s\n%s\n",input,flag); memset(input,'\0',sizeof(input)); memset(flag,'\0',sizeof(flag)); } return 0; }