1. 栈可以用来判断一个算术表达式中的括号是否匹配。编写一个函数,该函数接受一个算 术表达式作为参数,返回括号缺失的位置。下面是一个括号不匹配的算术表达式的例 子:2.3 + 23 / 12 + (3.14159×0.24。
function checkParentheses(expression) {
var stack = new Stack();
var unmatchedPositions = [];
for (var i = 0; i < expression.length; i++) {
var ch = expression[i];
if (ch === '(') {
stack.push(i);
} else if (ch === ')') {
if (stack.length() > 0) {
stack.pop();
} else {
unmatchedPositions.push(i);
}
}
}
while (stack.length() > 0) {
unmatchedPositions.push(stack.pop());
}
return unmatchedPositions.sort((a, b) => a - b);
}
const expression = '2.3) (+ 23 / 12 + (3.14159×0.24';
const result = checkParentheses(expression);
console.log(result);
2. 一个算术表达式的后缀表达式形式如下: op1 op2 operator 使用两个栈,一个用来存储操作数,另外一个用来存储操作符,设计并实现一个 JavaScript 函 数,该函数可以将中缀表达式转换为后缀表达式,然后利用栈对该表达式求值。
function infixToPostfix(expression) {
var precedence = {
'+': 1,
'-': 1,
'*': 2,
'/': 2,
'^': 3,
'(': 0
};
var operatorStack = new Stack();
var output = [];
for (var i = 0; i < expression.length; i++) {
var ch = expression[i];
if (!isNaN(ch) || ch === '.') {
output.push(ch);
} else if (ch === '(') {
operatorStack.push(ch);
} else if (ch === ')') {
while (operatorStack.peek() !== '(') {
output.push(' ');
output.push(operatorStack.pop());
output.push(' ');
}
operatorStack.pop();
} else if (precedence[ch]) {
while (operatorStack.length() > 0 && precedence[operatorStack.peek()] >= precedence[ch]) {
output.push(' ');
output.push(operatorStack.pop());
output.push(' ');
}
operatorStack.push(ch);
}
}
while (operatorStack.length() > 0) {
output.push(' ');
output.push(operatorStack.pop());
output.push(' ');
}
return output.join('');
}
function evaluatePostfix(postfixExpression) {
var operandStack = new Stack();
for (var i = 0; i < postfixExpression.length; i++) {
var token = postfixExpression[i];
if (token.trim() === '') {
continue;
}
else if (!isNaN(token)) {
operandStack.push(parseFloat(token));
} else {
var operand2 = operandStack.pop();
var operand1 = operandStack.pop();
var result;
switch (token) {
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
case '^':
result = Math.pow(operand1, operand2);
break;
}
operandStack.push(result);
}
}
return operandStack.pop();
}
var infixExpression = "2.3 + 23 / (12 + 3.14159) * 0.24";
var postfixExpression = infixToPostfix(infixExpression);
console.log("Postfix Expression:", postfixExpression);
console.log("Postfix Expression:", postfixExpression.split(' '));
var result = evaluatePostfix(postfixExpression.split(' '));
console.log("Result:", result);
3. 现实生活中栈的一个例子是佩兹糖果盒。想象一下你有一盒佩兹糖果,里面塞满了红 色、黄色和白色的糖果,但是你不喜欢黄色的糖果。使用栈(有可能用到多个栈)写一 段程序,在不改变盒内其他糖果叠放顺序的基础上,将黄色糖果移出。
function removeYellowCandies(candyBox) {
var tempStack = new Stack();
var originalStack = new Stack();
while (candyBox.length() > 0) {
var candy = candyBox.pop();
if (candy != 'yellow') {
tempStack.push(candy);
}
}
while (tempStack.length() > 0) {
originalStack.push(tempStack.pop());
}
return originalStack;
}
var candyBox = new Stack();
candyBox.push('red');
candyBox.push('yellow');
candyBox.push('white');
candyBox.push('yellow');
candyBox.push('red');
console.log("Original Candy Box:", candyBox.dataStore);
var cleanedCandyBox = removeYellowCandies(candyBox);
console.log("Cleaned Candy Box:", cleanedCandyBox.dataStore);
记录一下Stack的ABT实现:
function Stack() {
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
this.clear = clear;
this.length = length;
}
function push(element) {
this.dataStore[this.top++] = element;
}
function peek() {
return this.dataStore[this.top-1];
}
function pop() {
return this.dataStore[--this.top];
}
function clear() {
this.top = 0;
}
function length() {
return this.top;
}
function infixToPostfix(expression) {
var precedence = {
'+': 1,
'-': 1,
'*': 2,
'/': 2,
'^': 3,
'(': 0
};
var operatorStack = new Stack();
var output = [];
for (var i = 0; i < expression.length; i++) {
var ch = expression[i];
if (!isNaN(ch) || ch === '.') {
output.push(ch);
} else if (ch === '(') {
operatorStack.push(ch);
} else if (ch === ')') {
while (operatorStack.peek() !== '(') {
output.push(' ');
output.push(operatorStack.pop());
output.push(' ');
}
operatorStack.pop();
} else if (precedence[ch]) {
while (operatorStack.length() > 0 && precedence[operatorStack.peek()] >= precedence[ch]) {
output.push(' ');
output.push(operatorStack.pop());
output.push(' ');
}
operatorStack.push(ch);
}
}
while (operatorStack.length() > 0) {
output.push(' ');
output.push(operatorStack.pop());
output.push(' ');
}
return output.join('');
}
function evaluatePostfix(postfixExpression) {
var operandStack = new Stack();
for (var i = 0; i < postfixExpression.length; i++) {
var token = postfixExpression[i];
if (token.trim() === '') {
continue;
}
else if (!isNaN(token)) {
operandStack.push(parseFloat(token));
} else {
var operand2 = operandStack.pop();
var operand1 = operandStack.pop();
var result;
switch (token) {
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
case '^':
result = Math.pow(operand1, operand2);
break;
}
operandStack.push(result);
}
}
return operandStack.pop();
}
var infixExpression = "2.3 + 23 / (12 + 3.14159) * 0.24";
var postfixExpression = infixToPostfix(infixExpression);
console.log("Postfix Expression:", postfixExpression);
console.log("Postfix Expression:", postfixExpression.split(' '));
var result = evaluatePostfix(postfixExpression.split(' '));
console.log("Result:", result);