给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
方法1.栈
判断括号的有效性可以使用「栈」这一数据结构来解决。
我们遍历给定的字符串 s。当我们遇到一个左括号时,我们会期望在后续的遍历中,有一个相同类型的右括号将其闭合。由于后遇到的左括号要先闭合,因此我们可以将这个左括号放入栈顶。
当我们遇到一个右括号时,我们需要将一个相同类型的左括号闭合。此时,我们可以取出栈顶的左括号并判断它们是否是相同类型的括号。如果不是相同的类型,或者栈中并没有左括号,那么字符串 s 无效,返回 false。
bool isValid(string s) {
if (s.size() % 2 == 1)
return false;
if (s.size() == 0)
return true;
stack<char> brackets;
for (char c : s) {
if (c == '(' || c == '{' || c == '[')
brackets.push(c);
else if (brackets.empty())
{
printf("false");
return false;
}
else if (c == ')') {
char cnow = brackets.top();
if (cnow == '(')
brackets.pop();
else
{
printf("false");
return false;
}
}
else if (c == '}') {
char cnow = brackets.top();
if (cnow == '{')
brackets.pop();
else
{
printf("false");
return false;
}
}
else {
char cnow = brackets.top();
if (cnow == '[')
brackets.pop();
else
{
printf("false");
return false;
}
}
}
printf("true");
return brackets.empty();
}
方法2.replace函数
这是我在一篇博客中看到的方法,通过replace函数替代其中成对的括号,最后判断字符串是否还有剩余。
原代码是Java的代码,如下:
public boolean isValid(String s) {
//假如长度是1或者不为偶数
if(s.length()<2||s.length()%2!=0){
if(s.isEmpty()){
return true;
}
else{
return false;
}
}
int count = 0;
int length = s.length();
//循环替换,最大次数为s.length()/2
while(count<length/2){
s = s.replace("{}","").replace("[]","").replace("()","");
count++;
}
//假如循环替换完,还有值,那么肯定就不是对称结构
if(s.length()>0){
return false;
}
else{
return true;
}
}
随后我查看了C++中也有replace函数的声明,头文件为string。根据另一篇博客中对于replace函数的使用介绍修改了上面的代码,修改后的代码如下:
bool isValid2(string s) {
//假如长度是1或者不为偶数
if (s.length() < 2 || s.length() % 2 != 0) {
if (s.empty()) {
return true;
}
else {
return false;
}
}
int count = 0;
int length = s.length();
//循环替换,最大次数为s.length()/2
while (count < length / 2) {
//s = s.replace("{}",2, " ").replace("[]", "").replace("()", "");
//s = s.replace("{}", 2, " ");
s = s.replace(s.find("{"), 1, "t");
//s = s.replace(s.find("[]"), 2, " ");
//s = s.replace(s.find("()"), 2, " ");
count++;
}
//假如循环替换完,还有值,那么肯定就不是对称结构
if (s.length() > 0)
{
printf("false");
return false;
}
else {
printf("true");
return true;
}
}
但是这里遇到了一个问题:
s = s.replace(s.find("{"), 1, "t");
这行代码中我在s.find中查找括号时程序调试时会报错:
但是例如我给一个字母进行查找替换则不会出现问题。例如我给一个字符串然后让其查找a并用t替换:
s = s.replace(s.find(“a”), 1, “t”);
所以这里我不确定是C++中的replace函数不支持查找括号还是我这里的写法有问题。但是看到挺多地方提到Java中可以使用该函数解这道题。
整体代码如下:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stack>
#include <string>
using namespace std;
bool isValid(string s) {
printf("输入为:%s\n", s.c_str());
if (s.size() % 2 == 1)
return false;
if (s.size() == 0)
return true;
stack<char> brackets;
//for (char c : s)这是C++11中新增的一种循环写法,对数组(或容器类,如vector和array)的每个元素执行相同的操作,此外string类也支持这种对字符的遍历循环操作。
//for(double x:prices)。x最初表示数组prices的第一个元素,显示第一个元素后,不断执行循环,而x依次表示数组的其他元素。
for (char c : s) {
if (c == '(' || c == '{' || c == '[')
brackets.push(c);
else if (brackets.empty())
{
printf("结果为:false");
return false;
}
else if (c == ')') {
char cnow = brackets.top();
if (cnow == '(')
brackets.pop();
else
{
printf("结果为:false");
return false;
}
}
else if (c == '}') {
char cnow = brackets.top();
if (cnow == '{')
brackets.pop();
else
{
printf("结果为:false");
return false;
}
}
else {
char cnow = brackets.top();
if (cnow == '[')
brackets.pop();
else
{
printf("结果为:false");
return false;
}
}
}
printf("结果为:true");
return brackets.empty();
}
//bool isValid2(string s) {
// //假如长度是1或者不为偶数
// if (s.length() < 2 || s.length() % 2 != 0) {
// if (s.empty()) {
// return true;
// }
// else {
// return false;
// }
// }
// int count = 0;
// int length = s.length();
// //循环替换,最大次数为s.length()/2
// while (count < length / 2) {
// //s = s.replace("{}",2, " ").replace("[]", "").replace("()", "");
// //s = s.replace("{}", 2, " ");
// s = s.replace(s.find("{"), 1, "t");
// //s = s.replace(s.find("[]"), 2, " ");
// //s = s.replace(s.find("()"), 2, " ");
// count++;
// }
// //假如循环替换完,还有值,那么肯定就不是对称结构
// if (s.length() > 0)
// {
// printf("false");
// return false;
// }
// else {
// printf("true");
// return true;
// }
//}
bool replace(string str)
{
str = str.replace(str.find("a"), 2, "#");
printf("\n");
cout <<"输入:"<< str << endl;
return 0;
}
int main()
{
string res = "[{((}]";
//string res = "aacabd";
string str = "he is@ a@ good boy";
int n = 16;//数组元素的个数,即生成随机数的个数
int target = 30;
//int a[16];
isValid(res);
replace(str);
//Random(a, n, 1, 19);//生成随机数的通常范围为0~32767,这里通过取模控制取值为0~100
//search(a, n, target);
//printf("%s %d",a, n);
return 0;
}
效果如下:
参考:
https://leetcode-cn.com/problems/valid-parentheses/solution/you-xiao-de-gua-hao-by-leetcode-solution/
https://blog.csdn.net/qq_38455201/article/details/82887217
https://blog.csdn.net/wuxiecsdn/article/details/114589773
https://blog.csdn.net/qian2213762498/article/details/79530974
https://leetcode-cn.com/problems/valid-parentheses/