【C++题解】括号(括弧)匹配问题综合

文章目录

  • 1.表达式括号匹配(stack)
  • 2.括弧匹配检验(check)
  • 3.字符串匹配问题(strs)
  • 4.括号匹配(bracket)
  • 5.总结

1.表达式括号匹配(stack)

P a r t Part Part 1 1 1 读题

题目描述

假设一个表达式有英文字母(小写)、运算符( + + + — — × \times × ÷ ÷ ÷)和左右小(圆)括号构成,以“ @ @ @”作为表达式的结束符。

请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“ Y E S YES YES”;否则返回“ N O NO NO”。表达式长度小于 255 255 255左圆括号少于 20 20 20个。

输入格式

包括一行数据,即表达式

输出格式

包括一行,即“ Y E S YES YES” 或“ N O NO NO”。

输入样例1

2*(x+y)/(1-x)@

输出样例1

YES

输入样例2

(25+x)*(a*(a+b+b)@

输出样例2

NO

数据范围与提示

表达式 S S S的长度 ≤ 225 ≤225 225

P a r t Part Part 2 2 2 思路

根据题意,我们知道了本题需要我们在输入后,找到字符串中的" ( ( (“和” ) ) )“,然后进行计算,把” ( ( (“放入栈中,每当出现一个” ) ) )",就把栈顶减一,遇到结尾的 @ @ @后,截止运算,判断栈顶是否为 0 0 0,输出 Y E S YES YES N O NO NO

小tip:大家可以先根据思路,写一下代码哦!

P a r t Part Part 3 3 3 代码

#include
using namespace std;
int top;
int main(){
	string a; 
	char s[3000];
	cin>>a;
	int n=a.size();
	for(int i=0;i<n;i++){
		if(a[i]=='(')s[++top]=1;
		if(a[i]==')'){
			if(s[top]==1&&top>0)s[--top]=0;
			else{
				cout<<"NO";
				break;
			}
		}
		if(a[i]=='@'){
			if(top==0)cout<<"YES";
			else cout<<"NO";
		}
	}
	return 0;
}

2.括弧匹配检验(check)

P a r t Part Part 1 1 1 读题

题目描述

假设表达式中允许包含两种括号:圆括号和方括号,其嵌套的顺序随意,如 ( [ ] ( ) ) ([]()) ([]()) [ ( [ ] [ ] ) ] [([][])] [([][])]等为正确的匹配, [ ( ] ) [(]) [(]) ( [ ] ( ) ([]() ([]() ( ( ) ) ) ) (()))) (())))均为错误的匹配。

现在的问题是,要求检验一个给定表达式中的括弧是否正确匹配?

输入一个只包含圆括号和方括号的字符串,判断字符串中的括号是否匹配,匹配就输出“ O K OK OK” ,不匹配就输出“ W r o n g Wrong Wrong”。

输入格式

输入仅一行字符(字符个数 < 255 <255 255

输出格式

匹配就输出 “ O K OK OK” ,不匹配就输出“ W r o n g Wrong Wrong”。

输入样例

[(])

输出样例

Wrong

数据范围与提示

字符个数 n < 255 n<255 n255

P a r t Part Part 2 2 2 思路

看到题目,大家可能认为与题目1相类似,仅仅是多了一个 [ ] [] [],但是尝试后发现并没有想象中的那么简单,所以我们举例分析:

字符 n n n ( [ ) ] ([)] ([)]

下标 i i i 0123 0123 0123

s [ i ] s[i] s[i]是“ ( ( (”或是“ [ [ [”就无条件进入栈 a a a,将栈 a a a下标 + + t o p ++top ++top

s [ i ] s[i] s[i] ) ) )”就判断。若 a [ t o p ] a[top] a[top]是" ( ( (",则将 t o p − − top-- top

一定要注意啊!!!下次 + + t o p ++top ++top会覆盖掉 ) ) )”!!!

s [ i ] s[i] s[i]是 “ ] ] ]” 就判断。若 a [ t o p ] a[top] a[top]是“ [ [ [”,则将 t o p − − top-- top

一定要注意啊!!!下次 + + t o p ++top ++top会覆盖掉 ) ) )”!!!

a [ t o p ] a[top] a[top]不是" ( ( (",则将记录的 f f f值改为 1 1 1,直接 b r e a k break break

a [ t o p ] a[top] a[top]不是" [ [ [",则将记录的 f f f值改为 1 1 1,直接 b r e a k break break

P a r t Part Part 3 3 3 代码

#include
using namespace std;
int top;
bool f;
int main(){
	string s; 
	char a[3000];
	cin>>s;
	int l=s.size(),n,m;
	for(int i=0;i<l;i++){
		if(s[i]=='('||s[i]==')')n++;
		if(s[i]=='['||s[i]==']')m++;
		if(s[i]=='('||s[i]=='[')a[++top]=s[i];
        if(s[i]==')'){
            if(a[top]=='(')top--;
            else{
                f=1;
                break;
            }
        }
        if(s[i]==']'){
            if(a[top]=='[')top--;
        	else{
                f=1;
                break;
            }
        }
    }
    if(n%2==1||m%2==1){
        cout<<"Wrong";
       	return 0;
	}
    if(f==1)cout<<"Wrong";
    else cout<<"OK";
	return 0;
}

3.字符串匹配问题(strs)

P a r t Part Part 1 1 1 读题

题目描述

字符串中只含有括号 ( ) () () [ ] [] [] < > <> <> { } \{\} {} ,判断输入的字符串中括号是否匹配。

如果括号有互相包含的形式,从内到外必须是 ( ) () () [ ] [] [] < > <> <> { } \{\} {}

例如,输入 [ ( ) ] [()] [()] 输出 Y E S YES YES,而输入 ( [ ] ) ([]) ([]) ( [ ) ] ([)] ([)]都输出 N O NO NO

输入格式

第一行为一个整数 n n n,表示以下有多少个由括号组成的字符串。

接下来的 n n n行,每行都是一个由括号组成的长度不超过 255 255 255的字符串。

输出格式

n n n行,每行都是 Y E S YES YES N O NO NO

输入样例

5 
{}{}<><>()()[][] 
{{}}{{}}<<>><<>>(())(())[[]][[]] 
{{}}{{}}<<>><<>>(())(())[[]][[]] 
{<>}{[]}<<<>><<>>>((<>))(())[[(<>)]][[]] 
><}{{[]}<<<>><<>>>((<>))(())[[(<>)]][[]] 

输出样例

YES 
YES 
YES 
YES 
NO 

数据范围与提示

字符串长度 S ≤ 255 S≤255 S255

P a r t Part Part 2 2 2 思路

本题稍有难度,主要是在判断四个括号的大小关系以及判断前方括号类型(圆括号、方括号、花括号需要判断),不满足就输出 N O NO NO

P a r t Part Part 3 3 3 代码

方法1:有函数

#include
using namespace std;
int top,t,d[5];//1 <> 2 () 3 [] 4 {}
char s[10086];
bool f;
string a;
void wro(){
	cout<<"NO"<<endl;
	f=false;
	return;
}
void is_di(int x){
	for(int i=1;i<x;i++)if(d[i]!=0)wro();
}
int main(){
	cin>>t;
	for(int i=1;i<=t;i++){
		cin>>a;
		f=1,top=0; 
		d[1]=0,d[2]=0,d[3]=0,d[4]=0; 
		for(int j=0;j<a.size();j++){
			if(f==false)break;
			if(a[j]=='<'){
				d[1]++;
				s[++top]=a[j];
			}
			else if(a[j]=='('){
				is_di(2);
				d[2]++;
				s[++top]=a[j];
			}
			else if(a[j]=='['){
				is_di(3);
				d[3]++;
				s[++top]=a[j];
			}
			else if(a[j]=='{'){
				is_di(4);
				d[4]++;
				s[++top]=a[j];
			}
			else if(a[j]=='>'){
				if(s[top]=='<'&&d[1]!=0){
					top--;
					d[1]--;
				}
				else wro();
			}
			else if(a[j]==')'){
				if(s[top]=='('&&d[2]!=0){
					top--;
					d[2]--;
				}
				else wro();
			}
			else if(a[j]==']'){
				if(s[top]=='['&&d[3]!=0){
					top--;
					d[3]--;
				}
				else wro();
			}
			else if(a[j]=='}'){
				if(s[top]=='{'&&d[4]!=0){
					top--;
					d[4]--;
				}
				else wro();
			}
		}
		if(top==0&&f==true)cout<<"YES"<<endl;
		if(top!=0&&f==true)cout<<"NO"<<endl;
	}
	return 0;
}

方法2:无函数

#include
using namespace std;
int top,t,d[5];//1 <> 2 () 3 [] 4 {}
char s[10086];
bool f;
string a;
void is_di(int x){
	for(int i=1;i<x;i++){
		if(d[i]!=0){
			cout<<"NO"<<endl;
			f=false;
			break;
		} 
	}
}
int main(){
	cin>>t;
	for(int i=1;i<=t;i++){
		cin>>a;
		f=1,top=0; 
		d[1]=0,d[2]=0,d[3]=0,d[4]=0; 
		for(int j=0;j<a.size();j++){
			if(f==false)break;
			if(a[j]=='<'){
				d[1]++;
				s[++top]=a[j];
			}
			else if(a[j]=='('){
				is_di(2);
				d[2]++;
				s[++top]=a[j];
			}
			else if(a[j]=='['){
				is_di(3);
				d[3]++;
				s[++top]=a[j];
			}
			else if(a[j]=='{'){
				is_di(4);
				d[4]++;
				s[++top]=a[j];
			}
			else if(a[j]=='>'){
				if(s[top]=='<'&&d[1]!=0){
					top--;
					d[1]--;
				}
				else{
					cout<<"NO"<<endl;
					f=false;
					break;
				} 
			}
			else if(a[j]==')'){
				if(s[top]=='('&&d[2]!=0){
					top--;
					d[2]--;
				}
				else{
					cout<<"NO"<<endl;
					f=false;
					break;
				} 
			}
			else if(a[j]==']'){
				if(s[top]=='['&&d[3]!=0){
					top--;
					d[3]--;
				}
				else{
					cout<<"NO"<<endl;
					f=false;
					break;
				} 
			}
			else if(a[j]=='}'){
				if(s[top]=='{'&&d[4]!=0){
					top--;
					d[4]--;
				}
				else{
					cout<<"NO"<<endl;
					f=false;
					break;
				} 
			}
		}
		if(top==0&&f==true)cout<<"YES"<<endl;
		if(top!=0&&f==true)cout<<"NO"<<endl;
	}
	return 0;
}

P a r t Part Part 4 4 4 易错点 就因为这些我丢了 20 20 20分(悲)

1. 1. 1.循环开始之前,要判断 f f f是否已经为 f a l s e false false,若是就结束循环

2. 2. 2.每次不满足条件时,记得加上 f = f a l s e f=false f=false,要不然可能会在 N O NO NO多输出一个 Y E S YES YES

4.括号匹配(bracket)

P a r t Part Part 1 1 1 读题

题目描述

为了让 t y w z tywz tywz的同学们更富有智慧,贤者 w g y wgy wgy决定开设计算机基础、C语言程序设计、数据结构等课程。下头男 w h y why why听说课上可以玩电脑,于是兴冲冲地把有实力的 a y b ayb ayb拉上,报名参加了C语言基础课程

下头男 w h y why why当然什么都听不懂(毕竟他的智商只有 − 1145141919810 -1145141919810 1145141919810),所以每次上课他都全程跟有实力的 a y b ayb ayb玩斗地主,下课后请其他同学帮他写作业。 9 9 9个月后他把 t y w z tywz tywz所有的同学都委托了一遍,现在他找不到别人,只能再次找你了。

这次的作业是这样的:给你一个括号序列,其中有圆括号 ( ) () ()、方括号 [ ] [] []、花括号 {} 和尖括号 < > <> <>,请问该序列是否合法。

合法的括号序列可以按如下方式递归定义:

1. 1. 1.空序列是合法的;

2. 2. 2. A A A B B B是合法的括号序列,则 A B AB AB(将 B B B连接到 A A A的后方)也是合法的括号序列;

3. 3. 3. A A A是合法的括号序列,则在两端添加一对括号 ( A ) (A) (A) [ A ] [A] [A] A {A} A < A > <A>都是合法的括号序列。

输入格式

第一行是一个正整数 T T T,表示数据组数;

之后 T T T行,每行包含一个字符串,表示待判断的括号序列。保证字符串非空且只会包含 ( ) [ ] < > ()[]{}<> ()[]<> 8 8 8种字符。

输出格式

对于每组数据,若该序列是合法的则输出 Y e s Yes Yes,否则输出 N o No No

输入样例

3
(([]))
([(]))
{<><>}<{{(}}>)

输出样例

Yes
No
No

数据范围与提示

T ≤ 1 0 5 T≤10^{5} T105,所有测试数据的序列长度之和 ≤ 1 0 6 ≤10^{6} 106

本题共 10 10 10组测试文件,部分满足如下的附加限制条件:

测试点 1 − 3 1-3 13:序列中只包含圆括号

测试点 1 − 6 1-6 16 T ≤ 30 T≤30 T30

测试点 4 4 4:每个序列长度 ≤ 100 ≤100 100

测试点 1 、 5 、 6 1、5、6 156:每个序列长度 ≤ 1000 ≤1000 1000

P a r t Part Part 2 2 2 思路

本题较为简易,不需要判断大小,只需要判断括号是否正确,满足就输出 Y e s Yes Yes,不满足就输出 N o No No

P a r t Part Part 3 3 3 代码

#include
using namespace std;
int top,t,d[5];
char s[10000005],a[10000005];
bool f;
int main(){
    scanf("%d",&t);
    for(int i=1;i<=t;i++){
        cin>>a;
        f=true;
		top=0;
        int len=strlen(a);
        d[1]=0,d[2]=0,d[3]=0,d[4]=0;
        for(int j=0;j<len;j++){
            if(f==false)break;
            if(a[j]=='<'){
                d[1]++;
                s[++top]=a[j];
            }
			else if(a[j]=='('){
                d[2]++;
                s[++top]=a[j];
            } 
			else if(a[j]=='['){
                d[3]++;
                s[++top]=a[j];
            } 
			else if(a[j]=='{'){
                d[4]++;
                s[++top]=a[j];
            } 
			else if(a[j]=='>'){
                if(s[top]=='<'&&d[1] != 0){
                    top--;
                    d[1]--;
                } 
				else{
                	printf("No\n");
   					f=false;
    				break;
				}
            } 
			else if(a[j]==')'){
                if(s[top]=='('&&d[2]!=0){
                    top--;
                    d[2]--;
                } 
				else{
                	printf("No\n");
   					f=false;
    				break; 
				}
            } 
			else if(a[j]==']'){
                if(s[top]=='['&&d[3]!=0){
                    top--;
                    d[3]--;
                } 
				else{
                	printf("No\n");
   					f=false;
    				break; 
				}    
            } 
			else if(a[j]=='}'){
                if(s[top]=='{'&&d[4]!=0){
                    top--;
                    d[4]--;
                } 
				else{
                	printf("No\n");
   					f=false;
    				break; 
				}       
            }
        }
        if(top==0&&f==true)printf("Yes\n");
        if(top!=0&&f==true)printf("No\n");
    }
    return 0;
}

5.总结

括号(括弧)问题一直是初学栈时的最好练习题,但请注意题目要求

1. 1. 1.括号有哪些?

2. 2. 2.括号需要判断大小吗?

3. 3. 3.若需要,怎么判断?

听完后,是不是觉得很简单呢?赶快自己去试一下吧!!!

你可能感兴趣的:(C++题解,#,栈与深度优先搜索,c++,算法,开发语言)