文章目录
前言
常会碰到这样一类问题,例如:
//1.编写一个函数,接收一个算数表达式作为参数,返回括号的缺失位置
1.3+2 * 3 +(52%5
//2.实现一个normallize函数,将字符串转换为特定的数据结构
[a[b[c]]]//转换为{value:a,children:{value:b,children:{value:c}}
那么今天就来总结一下这类题目的解题思路:栈。
一、栈是什么?
栈是一种特殊的列表,栈内的元素只能通过列表的一端进行访问,这一段端称为栈顶。(先进后出)
对栈的操作主要是将一个元素压入栈和将一个元素弹出栈。入栈使用push()
方法,出栈使用pop()
方法。
二、栈的应用
1.判断是否是回文
function isPalindrome(str) {
let s = str.slice('');
let rts ='';
while(s.length>0) {
rts+=s.pop();//出栈
}
if(str === rts) {
return true;
} else {
return false;
}
}
2.编写一个函数,该函式接收一个算数表达式作为参数,返回括号缺失的位置
function demo (str) {
let sign = '(){}[]'
let s = []
for (let i = 0; i < str.length; i++) {
if (sign.includes(str[i])) {
let val = str[i];
switch (val) {
case '(':
case '[':
case '{': s.push(val); break;
case ')':
let map1 = s.pop();
if (map1 !== '(') {
return `位置${i}的)不匹配`
}
break;
case ']':
let map2 = s.pop();
if (map2 !== '[') {
return `位置${i}的]不匹配`
}
break;
case '}':
let map3 = s.pop();
if (map3 !== '{') {
return `位置${i}的}不匹配`
}
break;
}
}
}
if (s.length) {
return `符号${s.join()}没有闭合`
} else {
return '符号正确'
}
}
3.js实现括号匹配问题:
给定一个只包括“{”,“}”,“(”“)”,“[“ ,”]’’的字符串,判断字符串是否有效。有效字符串需要满足:
- 左括号必须用相同类型的右括号闭合
- 左括号必须以正确的顺序闭合(不得出现嵌套)
注意空字符串可被认为是有效的字符串;
算法流程:
-
遍历字符串的每一个字符
-
如果是左括号直接push入栈
-
如果是右括号,将栈顶的第一个元素取出来与当前的元素进行对比,如果不匹配,则return false;如果匹配那么就出栈
-
遍历完之后保证栈内为空
问题3和问题2实际是没有区别的,用上面的方法完全可以求解这个问题。但是我们现在用面向对象的思维来看这道题。
// 定义栈的类
class Stack {
constructor() {
this.stack = [];
}
push(item) {
return this.stack.push(item);
}
pop() {
return this.stack.pop();
}
// 查询栈顶的元素
peek() {
return this.stack[this.getSize() - 1];
}
//返回栈的长度
getSize() {
return this.stack.length;
}
// 栈的非空判断
isEmpty() {
return this.getSize() === 0;
}
}
function testIsValid(str) {
// 以左右括号来建立一个对象,key为左括号,value为右括号
var Map = {
"{": "}",
"(": ")",
"[": "]",
};
//实例化一个栈
const myStack = new Stack();
//遍历str字符串
for (let v of str) {
if (Map[v]) {
myStack.push(v); //是左括号,入栈
} else if (Object.values(Map).includes(v)) {
// 右括号 将当前的元素和栈顶的第一个元素进行匹配
let last = myStack.pop();
if (v !== Map[last]) return false;
} else {
//这里排除的是空字符的情况,如果不是左右括号而是其他的空字符串或者非法字符的话,将终止本次循环,执行下一次循环
continue;
}
}
//遍历完成之后要保证栈内要为空
return myStack.getSize() === 0;
}
4.实现一个normalize函数,能将特定的字符串转换为特定的结构化数据(阿里笔试题)
//例如将[a[b[c]]]转换为{ value: 'a', children: { value: 'b', children: { value: 'c' } } }
function normalize (str) {
let s = []; // 临时存储
let list = [];// 存储匹配的括号的下标
let obj = {};//存储结果
for (let i = 0; i < str.length; i++) {
let value = str[i]
switch (value) {
case '[':
s.push(i);
break;
case ']':
list.unshift([s.pop(), i]);
default:
break;
}
}
let [start, end] = list[0];
let parent = obj;
for (let i = 1; i < list.length; i++) {
let [a, b] = list[i];
let result = str.slice(start + 1, a) + str.slice(b + 1, end);
start = a;
end = b;
parent.value = result;
parent.children = {};
parent = parent.children;
}
// 处理list最后一个元素
let [x, y] = list[list.length - 1];
parent.value = str.slice(x + 1, y);
return obj;
}