括号匹配问题

前言

  • 周一是我女朋友的生日,无奈公司的接口需要我去调试,心里也确实放不下公司的事情,结果周末两天都在公司调试加班,今天周一我和女友都上班,唉,太感谢我女友了,一个男人的高度很大程度上取决于身边的女人啊,祝我宝贝璐璐生日快乐。
  • 我的博客都会根据自己的学习水平实时的进行更新,看到有些人转载我的博客没标明出处很上火,而且全是无脑照抄,真是无力吐嘈,感觉用链栈实现括号匹配反而复杂了,用顺序栈即可,重写了ac代码,贴出来跟大家共享

题目

题目描述:
    在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注.
输入:
    输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。
    注意:cin.getline(str,100)最多只能输入99个字符!
输出:
    对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配。
样例输入:
)(rttyy())sss)(
样例输出:
)(rttyy())sss)(
?            ?$


算法思想:

括号匹配是典型的栈的应用,思路如下:
  • 因为题目要求找出不匹配的左、右括号,因此需要两次遍历输入的字符串
  • 第一次(从左向右遍历字符串),
  1. 是左括号,则入栈,同时标记数组的相应位置置空格
  2. 是右括号,则检测栈是否为空,不为空,则判断有对应的左括号,左括号出栈,标记数组相应位置置空格;为空,则没有对应的左括号,标记数组置‘?’
  3. 其它字母,标记数组的相应位置置空格
  • 第二次(从右向左遍历字符串),
  1. 是右括号,则入栈
  2. 是左括号,则检测栈是否为空,不为空,则判断有对应的右括号,同时出栈;为空,则没有对应的左括号,标记数组置‘$’


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;
}


你可能感兴趣的:(括号匹配问题)