数据结构与算法JavaScript描述练习------第4章栈

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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值