我想获取堆栈的中间元素,所以我创建了一个函数deleteMid并递归调用remove函数来检查并弹出中间元素,但这里我得到的输出为undefined,所以请你如何纠正那个代码?代码如下。
function deleteMid(s, sizeOfs) {
let count = 0;
let mid = Math.floor(sizeOfs / 2);
remove(s, count, mid, sizeOfs);
}
function remove(s, count, mid, sizeOfs) {
if (count === mid) {
s.pop();
return;
}
let num = s.pop();
remove(s, count + 1, mid, sizeOfs);
s.push(num);
}
console.log(deleteMid([1, 2, 3, 4, 5], 5))
您的代码工作正常,只是您不应该通过 deleteMid
输出值
returned,而应该保留对作为参数传递给它的堆栈的引用。因此,在主程序中更改以下行:
console.log(deleteMid([1, 2, 3, 4, 5], 5));
至:
const stack = [1, 2, 3, 4, 5]; // Keep a reference to the stack
deleteMid(stack, stack.length);
console.log(stack); // Output the mutated stack
现在输出将是:
[1, 2, 4, 5]
不是你的问题,而是:
遗憾的是,您必须提供堆栈的长度作为单独的参数,并且在删除之后,您无法从函数中获得调整后的大小。数组有一个
length
属性,所以你可以使用它。如果这是一个不允许您使用 length
属性的作业,则创建一个维护 Stack
属性的 size
类。
您的
remove
函数参数太多。它不需要 sizeOfs
:除了将其传递给递归调用之外,它从不使用它。
您可以将
count
传递给递归调用,而不是使用 mid-1
参数(它会增加)。这会保存另一个参数。
对于整数除以 2,使用
>>
运算符而不是 Math.floor
更优雅。
数组有一个
splice
方法可以完成这项工作。但我想这是一个作业,要求您不要使用除 push
和 pop
之外的任何数组方法。
变量名称
s
表明它是一个字符串。相反,请使用更具描述性的名称,例如 stack
。
您的
remove
方法有两个地方调用 pop
。这可以在一个地方完成,将早期出口移到它之后。
这是您的代码,其中考虑了上述一些注释:
function deleteMid(stack, stackSize) {
// Use bitshift to integer-divide by 2.
// Don't pass count, nor sizeOfs as argument
remove(stack, stackSize >> 1);
}
function remove(stack, indexFromTop) {
const value = stack.pop();
if (indexFromTop == 0) { // Base case exit moved after the pop call.
return;
}
remove(stack, indexFromTop - 1);
stack.push(value);
}
const stack = [1, 2, 3, 4, 5];
deleteMid(stack, 5);
console.log(stack);
为了使更改后的堆栈大小可供调用者使用,并防止调用者使用除
push
和 pop
之外的任何其他数组属性,您可以定义一个 Stack
类,如下所示:
/* Define a class so that you can enforce that no Array properties other than
* push and pop can be used, and that you can maintain a size that is also
* available after deleting elements
*/
class Stack {
#stack; // Private array property so caller cannot access it nor its methods
constructor(...values) {
this.#stack = values;
}
// Only expose the stack-related methods
get length() {
return this.#stack.length;
}
push(value) {
this.#stack.push(value);
}
pop() {
return this.#stack.pop();
}
// Custom methods:
deleteMid() {
// Use bitshift to integer-divide by 2.
// Don't pass count, nor sizeOfs as argument
this.remove(this.length >> 1);
}
remove(indexFromTop) {
const value = this.pop();
if (indexFromTop == 0) { // Base case exit moved after the pop call.
return;
}
this.remove(indexFromTop - 1);
this.push(value);
}
// To help printing the stack (or for other purposes),
// make the stack iterable
*[Symbol.iterator]() {
yield* this.#stack;
}
}
const stack = new Stack(1, 2, 3, 4, 5);
stack.deleteMid();
console.log(...stack); // Use iterator to print the stack's values