栈及栈的应用
- stack:称作栈或堆叠,其特殊之处只允许在链表或数组的一端(堆栈顶端)插入(push)数据,输出数据(pop)
- 其特点是先进后出

栈的实现
<!--链表实现-->
import LinkedList from '../linked-list/LinkedList';
export default class Stack {
constructor() {
this.linkedList = new LinkedList();
}
/**
* @return {boolean}
*/
isEmpty() {
return !this.linkedList.tail;
}
/**
* @return {*}
*/
peek() {
if (!this.isEmpty()) {
return null;
}
return this.linkedList.tail.value;
}
/**
* @param {*} value
*/
push(value) {
this.linkedList.append(value);
}
/**
* @return {*}
*/
pop() {
const tailNode = this.linkedList.deleteTail();
return tailNode ? tailNode.value : null;
}
/**
* @return {*[]}
*/
toArray() {
return this.linkedList
.toArray()
.map(linkedListNode => linkedListNode.value)
.reverse();
}
/**
* @param {function} [callback]
* @return {string}
*/
toString(callback) {
return this.linkedList.toString(callback);
}
}
应用
- 简单的四则元算
import Stack from './Stack';
export default class InToPost {
constructor() {
this.theStack = new Stack();
this.output = [];
}
/**
* 转换为后缀表达式
*/
doTrans(str) {
this.output = [];
for (let i = 0, len = str.length; i < len; i++) {
const ch = str.charAt(i);
switch (ch) {
case '+':
case '-':
this.getOper(ch, 1);
break;
case '*':
case '/':
this.getOper(ch, 2);
break;
case '(':
this.theStack.push(ch);
break;
case ')':
this.getParen();
break;
default:
this.output.push(ch);
break;
}
}
while (!this.theStack.isEmpty()) {
this.output.push(this.theStack.pop());
}
return this.output;
}
getOper(opThis, prec1) {
while (!this.theStack.isEmpty()) {
const opTop = this.theStack.pop();
if (opTop === '(') {
this.theStack.push(opTop);
break;
} else {
let prec2 = 0;
if (opTop === '+' || opTop === '-') {
prec2 = 1;
} else {
prec2 = 2;
}
if (prec2 < prec1) {
this.theStack.push(opTop);
break;
} else {
this.output.push(opTop);
}
}
}
this.theStack.push(opThis);
}
getParen() {
while (!this.theStack.isEmpty()) {
const chx = this.theStack.pop();
if (chx === '(') {
break;
} else {
this.output.push(chx);
}
}
}
/**
* 计算
*/
calculation() {
const caStack = new Stack();
let num1 = 0;
let num2 = 0;
let ans = 0;
let ch;
for (let i = 0, len = this.output.length; i < len; i++) {
ch = this.output[i];
if (ch >= '0' && ch <= '9') {
caStack.push(parseInt(ch));
} else {
num2 = caStack.pop();
num1 = caStack.pop();
switch (ch) {
case '+':
ans = num1 + num2;
break;
case '-':
ans = num1 - num2;
break;
case '*':
ans = num1 * num2;
break;
case '/':
ans = num1 / num2;
break;
default:
break;
}
caStack.push(ans);
}
}
ans = caStack.pop();
return ans;
}
}
- 四则元算 目前仅支持10位以内计算
- 将中缀表达式3+2--->变为后缀表达式32+
- (1)从左到右逐个扫描中缀表达式中的各项,如果到达末尾则跳转转到(6),否则根据(2)~(5)的描述进行操作;
- (2)遇到操作数直接输出;
- (3)遇到运算符(设为a),则和栈顶的操作符(设为b)比较优先级,若a小于等于b的优先级,则连续出栈输出,直到a大于b的优先级或b为(,a进栈;
- (4)遇到(,进栈;
- (5)遇到),则连续出栈输出,直到遇到左括弧(为止。其中,(出栈但是并不输出;
- (6)输出栈中剩余的操作符。
-
计算后缀表达式的值,遇到数字压栈,遇到操作符取出数字计算结果,压栈,重复此过程至循环结束,取出数据即最后结果
-
分割符匹配
import Stack from './Stack';
export default class BracketChecker {
constructor() {
this.stack = new Stack();
}
check(str) {
let isMatch = false;
const map = new Map([
['{', '}'],
['[', ']'],
['(', ')']
]);
const keys = [...map.keys()];
const values = [...map.values()];
for (let i = 0, len = str.length; i < len; i++) {
const ch = str.charAt(i);
if (keys.includes(ch)) {
this.stack.push(ch);
} else if (values.includes(ch)) {
if (!this.stack.isEmpty()) {
const chx = this.stack.pop();
// 遇到)括号出栈,并从map里面找到)括号需要配对的(括号,相等则匹配成功
const needKey = [...map.entries()].filter((el) => {
return el[1] === ch;
}).pop().shift();
isMatch = needKey === chx;
}
}
}
return isMatch && this.stack.isEmpty();
}
}