括号配对问题 【刷题反思】
1. 判断括号配对
1.1 题目
题目描述:给定一个只包括 '(' , ')' , '{' ,'}' , '[' , ']' 的字符串 s ,判断字符串是否有效
有效字符串:1. 左括号必须用相同类型的右括号闭合
2. 左括号必须以正确的顺序闭合
3. 每个右括号都有⼀个对应的相同类型的左括号
示例:输入:s = "()[]{}"
输出:true
class Solution {
public:
bool isValid(string s) {
}
};
1.2 思想
栈的“后进先出”特性,我们可以把左括号依次放入一个栈中,当遇到右括号时,从栈中提取栈顶元素和右括号比较,由于栈的“先进后出”的特性,这个栈顶左括号在顺序上和右括号相匹配,只需判断是否是一个类型即可
1.3 模拟实现
#include<stack>
class Solution {
public:
bool isValid(string s) {
//因为要匹配括号,所以栈的类型为char
stack<char> stk;
//遍历这个字符串的每一个字符
for (auto ch : s)
{
//遇到左括号放入栈中
if (ch == '(' || ch == '{' || ch == '[') stk.push(ch);
else
{
//遇到右括号先判断栈是否为空,为空直接返回
if (stk.empty()) return false;
//如果不为空,就弹出栈顶元素匹配,不匹配返回false
int ch1 = stk.top();
if (ch == ']' && ch1 != '[') return false;
if (ch == '}' && ch1 != '{') return false;
if (ch == ')' && ch1 != '(') return false;
//如果相匹配,别忘记去除栈顶元素,接着判断其他组
stk.pop();
}
}
//如果全匹配,那栈应该为空
return stk.empty();
}
};
2. 添加正确的括号
2.1 题目
题目描述:定义如下规则:
1. 空串是「平衡括号序列」
2. 若字符串 S 是「平衡括号序列」,那么 [S] 和 (S) 也都是「平衡括号序列」
若字符串 A 和 B 都是「平衡括号序列」,那么 AB(两字符串拼接起来)也是「平衡括号序列」。
例如,下面的字符串都是平衡括号序列:
(())
,([])
,()[]
,()[()]
而以下几个则不是:
)(
,())
,([()
现在,给定一个仅由 (
,)
,[
,]
构成的字符串 s,请你按照如下的方式给字符串中每个字符配对:
从左到右扫描整个字符串。
对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近的未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。
配对结束后,对于 s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配
输入描述:输入只有一行一个字符串,s;s的长度不超过 100 ,只含 (,),[,] 四种字符
示例:输入:([()
输出:()[]()
2.2 思想
和前一道题一样,我们可以用栈来存储左括号,遇到右括号时弹栈和右括号比较,值得注意的是,这道题要求补上对应括号,所以我们需要知道不匹配括号的位置,栈的类型为int可以标记字符在字符串里的位置
2.3 模拟实现
#include<iostream>
using namespace std;
#include<stack>
const int N = 110;
//定义布尔数组标记不合格的字符
bool a[N];
//定义int类型的stack,可以标记位置
stack<int> stk;
string s;
int main()
{
cin >> s;
//遍历字符串
for (int i = 0; i < s.size(); i++)
{
char ch = s[i];
//左括号,将在字符串的对应位置压栈
if (ch == '(' || ch == '[') stk.push(i);
else
{
//遇到右括号,栈为空,bool数组默认该位置为false
if (stk.empty()) continue;
//得到栈顶左括号
char tmp = s[stk.top()];
//和右括号匹配,相匹配标记左括号和右括号位置为true
if ((ch == ')' && tmp == '(')|| (ch == ']' && tmp == '['))
{
a[i] = true;
a[stk.top()] = true;
stk.pop();
}
}
}
//原字符串标记完毕,补到新的字符串
string ret = "";
for (int i = 0; i < s.size(); i++)
{
//原字符串标记为true,直接加
if (a[i]) ret += s[i];
else
{
char ch = s[i];
if (ch == '(')
{
ret += ch;
ret += ')';
}
else if (ch == '[')
{
ret += ch;
ret += ']';
}
else if (ch == ')')
{
ret += '(';
ret += ch;
}
else if(ch==']')
{
ret += '[';
ret += ch;
}
}
}
cout << ret << endl;
return 0;
}