括号序列配对问题

这是最近在ACM练习场上看到的题目:
现在,有一行括号序列,请你检查这行括号是否配对。第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符。每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No。

用栈结构实现最简单,但是一开始我没想到。大体思路如下:
①从输入的每个的字符串的遍历每个字符
②如果遇到 '('或'['就压入栈中,因为如果该字符串匹配的话,这两种字符总是先出现在字符串中
③如果遇到')'或']',就匹配栈顶的元素,如果栈顶元素是对应的'('或者'[',说明匹配,将栈顶元素弹出;如果不匹配,因为这种'([)]'交叉的字符串是不匹配的,直接跳出循环
④重复②③直到遍历完字符串

开始,我用java语言实现,但是测试时间超时,代码如下:`

import java.util.Scanner;
import java.util.Stack;
public class Main {
   public static void main(String[] args) {
                int i;   //循环变量
		int n;   //存储输入的字符串数量
		char temp;  //临时变量
		String string=null;
		Stack<Character> stack=new Stack<Character>();   //用于判断字符串是否配对
		boolean[]  flag;   //存储每个是否配对的信息
		Scanner scanner=new Scanner(System.in);  //接收参数
		n=scanner.nextInt();   //接收输入的第一个参数
		flag=new boolean[n];
		for(i=0;i<n;i++){
			//接收输入的字符串
			string=scanner.next();
			flag[i]=true;   //默认为配对
			//如果字符串长度为奇数,不能匹配
			if(string.length()%2!=0){
				flag[i]=false; 
				continue;
			}
			//字符串第一个字符为)或]不匹配
			if(string.charAt(0)==']'||string.charAt(0)==')'){
				flag[i]=false; 
				continue;
			}
			for(int j=0;j<string.length();j++){
				//字符为(  [ 则入栈
				temp=string.charAt(j);
				if(temp=='['||temp=='('){
					stack.push(temp);
				}else if(temp==']'){
					//如果栈顶元素不能配对,说明不匹配
					if(stack.pop()!='['){
						flag[i]=false;
						stack.clear();
						break;
					}
				}else{
					if(stack.pop()!='('){
						flag[i]=false;
						stack.clear();
						break;
					}
				}			
			}		
		}
		//控制输出
		for(i=0;i<n;i++){   
			if (flag[i]) {
				System.out.println("Yes");
			}else {
				System.out.println("No");
			}
		}
	}
}

后头我又用c语言实现了一遍,并且对照了大牛的代码,没有发现什么区别,可是我的代码虽然正确,但是运行依然超时,十分不解,有大神帮忙看看么。

#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;
int main()
{
	int n=0;   //存储输入的字符串数量
	char temp;  //临时变量
	bool flag;  //存储是否为配对的括号
	char str[20];  //存储输入的字符串
	stack<char> myStack;  //用于判断字符串是否配对
	int length=0;

	int number;
	scanf("%d", &n);
	while (n--) //循环控制 输入的字符串个数
	{
		flag = true;
		scanf("%s", &str);
		length = strlen(str);
		//如果字符串长度为奇数,不能匹配
		if (length % 2 != 0) {
			printf("No\n");
			continue;
		}
		//如果第一个字符为] 或) 不匹配
		if (str[0] == ']' || str[0] == ')') {
			printf("No\n");
			continue;
		}
		else 
		{
			for (unsigned int j = 0; j< length; j++)
			{
				//字符为(  [ 则入栈
				temp = str[j];
				if (temp == '[' || temp == '(') {
					myStack.push(temp);

				}
				else if ((temp == ']') && (myStack.top() != '[') || (temp == ')') && (myStack.top() != '(')) {
					//如果栈顶元素不能配对,说明不匹配
					flag = false;
					break;
				}
				else {
					myStack.pop();
				}
			}

			if (flag)
			{
				printf("Yes\n");
			}
			else
			{
				//清空栈,以便下个字符串使用
				while (!myStack.empty())
				{
					myStack.pop();
				}
				printf("No\n");
			}
		}
	}
	return 0;
}




  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值