问题描述
对一串字符串进行匹配括号是否匹配,例如 "{a(g[c]f)d}"符号的顺序以及数量都是匹配的,"{a[b(d]d}" 括号是不匹配的
问题解析
算法matchBracket
- 定义空栈用于存在左右符号
- 循环字符串拿出当前字符
- 在左括号中存在就
push进队列中 - 在右括号中进行匹配,如果包含就拿出栈中最后进入的符号进行匹配,如果不匹配就代表整个字符串不匹配
- 返回最后的栈是否长度为0,0代表匹配,否则就是不匹配
算法复杂度
- 时间复杂度: O(n) 单次循环
- 空间复杂度: O(n) stack占用空间
/**
* 括号匹配
* 对一串字符串进行匹配括号是否匹配,例如 "{a(g[c]f)d}" 符号的顺序以及数量都是匹配的,"{a[b(d]d}" 括号是不匹配的
*/
export function matchBracket(str: string): boolean {
let length = str.length;
if (length === 0) return true;
// 定义左括号字符串
let leftSybmol = "{[(";
// 定义右括号字符串
let rightSybmol = "}])";
// 定义栈队列
let stack = [];
// 循环获取当前匹配字符内容
for (let i = 0; i < length; i++) {
let s = str[i];
// 如果左括号包含
if (leftSybmol.includes(s)) {
stack.push(s);
//如果右括号包含
} else if (rightSybmol.includes(s)) {
// 获取当前栈队列中最顶部的符号
let top = stack[stack.length - 1];
// 进行匹配校验
if (isMatch(top, s)) {
stack.pop();
} else {
return false;
}
}
}
// 返回最后的栈是否长度为0,0代表匹配,否则就是不匹配
return stack.length === 0;
}
/**
* 判断左括号和右括号是否匹配
* @param left 左括号
* @param right 右括号
* @returns 是否匹配
*/
function isMatch(left: string, right: string): boolean {
if (left === "(" && right === ")") return true;
if (left === "[" && right === "]") return true;
if (left === "{" && right === "}") return true;
return false;
}
测试算法
测试算法正确性
/**
* 测试代码
*/
(function () {
const str = "{x(k[l]j)y}";
console.log(MatchBracket(str));
})();
测试结果图
测试用例
- 测试正常数据下结果
- 测试空字符串
- 测试右括号不匹配
- 测试左括号不匹配
- 测试右括号开头
/**
* 括号匹配单元测试
*/
import { MatchBracket } from "./match-bracket";
describe("括号匹配单元测试", () => {
it("正常情况", () => {
const str = "{x(k[l]j)y}";
let result = MatchBracket(str);
expect(result).toBe(true);
});
it("空字符串", () => {
const str = "";
let result = MatchBracket(str);
expect(result).toBe(true);
});
it("右括号不匹配", () => {
const str = "{x(k[l]y)j)y";
let result = MatchBracket(str);
expect(result).toBe(false);
});
it("左括号不匹配", () => {
const str = "x(k[l]y)j)y}";
let result = MatchBracket(str);
expect(result).toBe(false);
});
it("右括号开头", () => {
const str = "}{x(k[l]y)j)y}";
let result = MatchBracket(str);
expect(result).toBe(false);
});
});