如何用JavaScript算法统计自定义Stack对象的元素数量?
统计自定义Stack对象的元素数量
问题背景
需要编写JavaScript算法统计Stack对象的元素数量,该Stack提供以下方法:
stack:存储零或多个值的栈实例.pop():弹出栈顶元素并返回.push():向栈顶压入元素.peek():查看栈顶元素,不修改栈结构
尝试直接访问stack.length返回undefined,代码如下:
function countValues(stack) { return stack.length }
Stack类的实现代码:
class Stack { constructor(...values) { const data = {}; let index = 0; this.push = function (value) { if (arguments.length < 1) { throw new TypeError('stack.push() requires a value argument'); } if (typeof value === 'undefined') { throw new TypeError('stack.push(value) received undefined'); } data[index] = value; index++; }; this.pop = function () { const last = index - 1; if (last < 0) return; const value = data[last]; delete data[last]; index = last; return value; }; this.peek = function () { const last = index - 1; if (last < 0) return; return data[last]; }; this.print = function () { if (index === 0) { return 'Stack { <empty> }'; } let output = ' }'; let last = index - 1; for (; last > 0; last--) { output = ' <- ' + JSON.stringify(data[last]) + output; } output = JSON.stringify(data[last]) + output; return 'Stack { ' + output; }; for (let i = 0; i < values.length; i++) { this.push(values[i]); } Object.freeze(this); } }
问题原因
当前Stack类的元素计数依赖构造函数内的私有变量index,但没有将其作为实例属性或getter暴露出来,因此直接访问stack.length会得到undefined。
解决方案
方案1:修改Stack类,添加length属性
在Stack构造函数中,通过Object.defineProperty添加length的getter方法,这样外部就能直接通过stack.length获取元素数量:
class Stack { constructor(...values) { const data = {}; let index = 0; this.push = function (value) { if (arguments.length < 1) { throw new TypeError('stack.push() requires a value argument'); } if (typeof value === 'undefined') { throw new TypeError('stack.push(value) received undefined'); } data[index] = value; index++; }; this.pop = function () { const last = index - 1; if (last < 0) return; const value = data[last]; delete data[last]; index = last; return value; }; this.peek = function () { const last = index - 1; if (last < 0) return; return data[last]; }; this.print = function () { if (index === 0) { return 'Stack { <empty> }'; } let output = ' }'; let last = index - 1; for (; last > 0; last--) { output = ' <- ' + JSON.stringify(data[last]) + output; } output = JSON.stringify(data[last]) + output; return 'Stack { ' + output; }; for (let i = 0; i < values.length; i++) { this.push(values[i]); } // 添加length属性的getter Object.defineProperty(this, 'length', { get: () => index, enumerable: true }); Object.freeze(this); } }
修改后,原countValues函数即可正常工作:
function countValues(stack) { return stack.length; }
方案2:不修改Stack类,通过现有方法统计
如果无法修改Stack类,可以通过临时存储栈元素的方式统计数量,最后恢复原栈结构:
function countValues(stack) { let count = 0; const tempStack = []; // 弹出所有元素并计数 while (stack.peek() !== undefined) { tempStack.push(stack.pop()); count++; } // 将元素重新压回原栈 while (tempStack.length > 0) { stack.push(tempStack.pop()); } return count; }
这个方法利用peek()判断栈是否为空,通过临时数组保存弹出的元素,统计完成后再将元素按原顺序压回栈,不会改变栈的初始状态。
内容的提问来源于stack exchange,提问作者poopmachine
相关产品推荐
相关产品推荐

