栈的应用之括号匹配
除了逆序输出问题之外,括号匹配问题也是栈的一个典型应用,即检查表达式中的括号是否完全匹配,例如对于表达式a / ( (b + c) *d 和a / ( (b + c) *d ),前者的括号不匹配而后者的括号匹配。
问题描述
题目描述:
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母:规定(与常见的算数式子一样)任何一个左括号都从内到外与它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来的字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$“标注,不能匹配的右括号用”?"标注。
输入描述:
输入包含多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。
输出描述:
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由" $ “、” ? " 和空格组成," $ " 和 " ? "表示与之对应的左括号和右括号不能匹配。
输入:
)(rttyy())sss)(
输出:
)(rttyy())sss)(
? ?$
算法思想
每个右括号必定要与之前未被匹配的离它最近的一个进行匹配。因此,可以从左至右的顺序遍历整个字符串:
遍历过程中如果遇到左括号,就将其放入栈中以待后续右括号的匹配;
遇到右括号,若此时栈非空,则栈顶左括号必定和当前右括号匹配;相反,若此时栈为空,则表示当前右括号不存在与之匹配的左括号,右括号匹配失败。
当字符串全部遍历完后,若栈非空,表明栈中的左括号不存在与之匹配的右括号,左括号匹配失败。
实现代码:
#include<bits/stdc++.h>
using namespace std;
stack<char> brackets;
int main(){
string str;
while(cin>>str){
string answer(str.size(),' '); //设为 输入长度个 空格
for(int i=0; i<str.size(); i++){
if(str[i] == '(' ){
brackets.push(i); //压入左括号下标
}else if(str[i] == ')' ){ //如果是右括号
if(!brackets.empty()){
brackets.pop(); //栈不空则弹出,即有左括号匹配
}else{
answer[i] = '?'; //右括号不匹配
}
}
}
while(!brackets.empty()){
answer[brackets.top()] = '$'; //左括号不匹配
brackets.pop();
}
cout<<str<<endl;
cout<<answer<<endl;
}
return 0;
}