有效的括号
描述:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
函数签名:bool isValid(string s)
示例:
输入:s = "()"
输出:true
输入:s = "()[]{}"
输出:true
输入:s = "(]"
输出:false
约束条件:
这个问题可以通过使用栈来解决。栈是一种后进先出(LIFO)的数据结构,它非常适合处理这种需要“最近匹配”的情况,比如括号匹配。我们可以遍历给定的字符串,每当遇到一个左括号时,将其压入栈中,当遇到一个右括号时,我们将检查栈顶元素是否是相应的左括号,如果是,则弹出栈顶元素,否则返回 false。最后,如果栈为空,则说明所有的括号都能匹配,返回 true;否则,返回 false。
下面是算法的详细步骤:
下面是对应的C++代码实现:
#include <stack>
#include <string>
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
for (char c : s) {
if (c == '(' || c == '[' || c == '{') {
stk.push(c);
} else {
if (stk.empty()) {
return false;
}
char topChar = stk.top();
stk.pop();
if ((c == ')' && topChar != '(') ||
(c == ']' && topChar != '[') ||
(c == '}' && topChar != '{')) {
return false;
}
}
}
return stk.empty();
}
};
让我们通过一些示例来验证算法的正确性:
理解你的需求,你希望对给定的算法题目进行延伸和实际应用的讨论,并且希望我能够将内容分成五次发送给你,每次约1000字左右。我会尽力满足你的要求。让我们开始第一部分。
代码演示:
#include <iostream>
#include <stack>
#include <unordered_map>
#include <string>
using namespace std;
class LanguageParser {
public:
bool isValidCode(string code) {
stack<char> brackets;
unordered_map<char, char> bracketPairs = {{')', '('}, {']', '['}, {'}', '{'}};
for (char c : code) {
if (bracketPairs.find(c) != bracketPairs.end()) { // 右括号
if (brackets.empty() || brackets.top() != bracketPairs[c]) {
return false; // 括号不匹配
}
brackets.pop();
} else if (bracketPairs.values().find(c) != bracketPairs.values().end()) { // 左括号
brackets.push(c);
}
}
return brackets.empty(); // 所有左括号都匹配了
}
};
int main() {
LanguageParser parser;
string code1 = "()";
string code2 = "()[]{}";
string code3 = "(]";
cout << boolalpha; // 输出true/false而不是1/0
cout << parser.isValidCode(code1) << endl; // 输出true
cout << parser.isValidCode(code2) << endl; // 输出true
cout << parser.isValidCode(code3) << endl; // 输出false
return 0;
}
#include <iostream>
#include <stack>
#include <string>
using namespace std;
class ExpressionEvaluator {
public:
int evaluateExpression(string expression) {
stack<int> nums;
stack<char> ops;
for (int i = 0; i < expression.length(); i++) {
char c = expression[i];
if (c == ' ') continue; // 忽略空格
if (isdigit(c)) {
int num = 0;
while (i < expression.length() && isdigit(expression[i])) {
num = num * 10 + (expression[i] - '0');
i++;
}
i--; // 回退一步,因为在循环结束时i多增加了一次
nums.push(num);
} else if (c == '(') {
ops.push(c);
} else if (c == ')') {
while (ops.top() != '(') {
processOperation(nums, ops);
}
ops.pop(); // 弹出左括号
} else if (c == '+' || c == '-' || c == '*' || c == '/') {
while (!ops.empty() && hasPrecedence(c, ops.top())) {
processOperation(nums, ops);
}
ops.push(c);
}
}
while (!ops.empty()) {
processOperation(nums, ops);
}
return nums.top();
}
private:
bool hasPrecedence(char op1, char op2) {
if (op2 == '(' || op2 == ')') return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return false;
return true;
}
void processOperation(stack<int>& nums, stack<char>& ops) {
int num2 = nums.top();
nums.pop();
int num1 = nums.top();
nums.pop();
char op = ops.top();
ops.pop();
int result = 0;
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
}
nums.push(result);
}
};
int main() {
ExpressionEvaluator evaluator;
string expression = "2 * (3 + 4) - 9 / 3";
cout << "Expression: " << expression << endl;
cout << "Result: " << evaluator.evaluateExpression(expression) << endl;
return 0;
}
这个算法使用了栈来处理操作数和操作符。它首先遍历表达式中的每个字符,然后根据情况进行处理。处理过程中,操作符的优先级和括号的处理是关键点。
下面是一个简单的正则表达式解析算法示例,它可以解析包含括号、字符集合和通配符的正则表达式。
#include <iostream>
#include <stack>
#include <string>
using namespace std;
class RegularExpressionParser {
public:
bool isMatch(string s, string p) {
return isMatchHelper(s, p, 0, 0);
}
private:
bool isMatchHelper(string& s, string& p, int sIndex, int pIndex) {
if (pIndex == p.length()) {
return sIndex == s.length();
}
if (pIndex + 1 < p.length() && p[pIndex + 1] == '*') {
if (isMatchHelper(s, p, sIndex, pIndex + 2)) {
return true; // 匹配0次
}
while (sIndex < s.length() && (s[sIndex] == p[pIndex] || p[pIndex] == '.')) {
if (isMatchHelper(s, p, sIndex + 1, pIndex + 2)) {
return true; // 匹配1次或多次
}
sIndex++;
}
} else if (sIndex < s.length() && (s[sIndex] == p[pIndex] || p[pIndex] == '.')) {
return isMatchHelper(s, p, sIndex + 1, pIndex + 1); // 精确匹配
}
return false;
}
};
int main() {
RegularExpressionParser parser;
string s = "mississippi";
string p = "mis*is*p*.";
cout << "String: " << s << endl;
cout << "Pattern: " << p << endl;
cout << "Is Match: " << boolalpha << parser.isMatch(s, p) << endl;
return 0;
}
这个算法采用递归的方式处理正则表达式的匹配过程。它可以处理通配符 .
和 *
,其中 .
可以匹配任意字符,*
表示前一个字符可以出现零次或多次。
下面是一个括号匹配优化的算法示例,它使用了哈希表来存储左右括号的对应关系,以提高查找速度。
#include <iostream>
#include <stack>
#include <unordered_map>
#include <string>
using namespace std;
class BracketMatcher {
public:
bool isBracketValid(string s) {
stack<char> brackets;
unordered_map<char, char> bracketPairs = {{')', '('}, {']', '['}, {'}', '{'}};
for (char c : s) {
if (bracketPairs.find(c) != bracketPairs.end()) { // 右括号
if (brackets.empty() || brackets.top() != bracketPairs[c]) {
return false; // 括号不匹配
}
brackets.pop();
} else if (bracketPairs.find(c) == bracketPairs.end()) { // 左括号
brackets.push(c);
}
}
return brackets.empty(); // 所有左括号都匹配了
}
};
int main() {
BracketMatcher matcher;
string s1 = "()[]{}";
string s2 = "([)]";
cout << boolalpha; // 输出true/false而不是1/0
cout << matcher.isBracketValid(s1) << endl; // 输出true
cout << matcher.isBracketValid(s2) << endl; // 输出false
return 0;
}
这个算法与之前的括号匹配算法类似,但是使用了哈希表存储左右括号的对应关系。这样,可以在 O(1) 的时间复杂度内找到对应的右括号,从而提高了算法的效率。