【问题标题】:Return node position in list based on value using recursion使用递归根据值返回列表中的节点位置
【发布时间】:2022-12-17 23:09:56
【问题描述】:

我的任务是用 JavaScript 为列表编写一些函数,以完成我在 Odin 项目中的旅程。我现在的挣扎是从参数返回具有相同值的节点的位置。递归工作正常,更新旨在在节点值与参数值匹配时返回的变量计数也是如此。控制台抛出undefined,我试图将计数存储在一个单独的变量中,但没有成功。我检查了一些论坛答案以找出我犯错的地方,但我的代码非常接近投票的答案。 JavaScript 是否有我应该知道的处理递归的特定方法?

这是我的代码:

function valuePosition(node, value, count){
    if(node.next === null && node.value !== value){
      console.log('Not in the list');
      return 0;
    }

    if(node.value !== value){
      console.log('Not yet');
      return valuePosition(node.next,value, count+1);
    }else if(node.value === value){
      console.log('Found!');
      return position;
    }
  }

干杯!

[更新] 基于我最近与@ScottSauyet 的来回交流,我想用更多上下文来补充问题的描述。所以这是递归函数加上包装它的工厂。

class Node{
  static count = 0;
  constructor(value){
    ++Node.count;
    this.value = value;
    this.next = null;
    this.previous = null;
  }
} 

function List(value){
//some other methods here
  function valuePosition(node, value, count){
    if(node.next === null && node.value !== value){
      return 0;
    }

    if(node.value !== value){
      return valuePosition(node.next,value, count+1);
    }else if(node.value === value){
      return count;
    }
  }
  return{
    root: new Node(value),
    //some methods here
    find(value){
      valuePosition(this.root);
    }
  }
}

const list = List(89);
list.appendNode(98);
list.appendNode(9835);
list.appendNode(8245);
list.prependNode(9834);
list.prependNode(2345);
console.log(list.find(8245));
//OUTPUT: Undefined

我发现无法返回计数的主要问题。基本上,你不能从工厂或班级做到这一点(我已经试过了)。但是,如果我在工厂外运行 valuePosition 函数作为隔离代码 sn-p,它会产生奇迹

【问题讨论】:

  • 我认为这就像你 return position 一样简单,而你可能想 return countposition 未定义。不过,我建议 position 是参数的更好名称。类似于const valuePosition = (node, value, pos) => node .value == value ? pos : node .next == null ? -1 : valuePosition (node .next, value, pos + 1)。请注意,-1 是 JS 中未找到值的惯用信号。
  • 嗨@ScottSauyet!是的,我的名字错了,我以为我已经在 Stackoverflow 中编辑过了。尽管您的评论对于改进我当前的代码非常有用。感谢那!现在发生的情况是,递归函数不适用于工厂或类,但如果有意义的话,它可以作为代码片段取出并执行。我将再次编辑问题以避免将来对想要提出建议的人造成混淆。
  • 实际上我会保留原件,否则 cmets 的这个线程会误导其他社区成员。
  • 您显示的代码在使用 valuePosition 以外的其他方面被破坏。它没有实现 append/prependNode 。但关键问题可能是您的 find 函数不返回任何内容,只是调用 valuePosition 并忽略其结果。
  • 感谢@ScottSauyet 的评论!我应该包括我在最近的更新中已经实现的那些功能。我只是想尽可能避免问题中的噪音,但这不是一个好主意,我会更好地更新我发布的内容。刚刚测试了你的建议并且它有效,所以我将重构代码并更新答案。

标签: javascript list recursion


【解决方案1】:

事实证明,我编写了一个类似的函数,它输出一个包含每个节点值的串联字符串。同样,我无法获得递归的最终结果,所以我发现我的函数在工厂内部。通过取出工厂的递归函数,我可以获得递归的最终结果,这意味着围绕我的递归的上下文实际上是导致问题的原因。我将尝试以不同的方式调用该函数以保留工厂,但我可能会发现自己将我的代码重构为一个类。

[更新]

我只需要在 find() 中返回 valuePosition。这是我的代码的最终版本。

class Node{
  static count = 0;
  constructor(value){
    ++Node.count;
    this.value = value;
    this.next = null;
    this.previous = null;
  }
}


function List(value) {
  
  function valuePosition (node, value, position){
    if(node.next === null && node.value !== value){
      return -1;
    }
    if(node.value !== value){
      return valuePosition(node.next,value, position+1);
    }else if(node.value === value){
      return position;
    }
  }

  function checkNextNode(node) {
    if (node.next !== null) {
      return checkNextNode(node.next);
    } else {
      return node;
    }
  }

  function containsValue(node, value){
    if(node.next === null && node.value !==value){
      return false;
    }

    if(node.value !== value){
      containsValue(node.next,value);
    }else if(node.value === value){
      return true;
    }
  }

  function printNodeValue(node){
    if(node.next === null){
      return `(${node.value})`;
    }
    return `(${node.value})->` + printNodeValue(node.next);
  }

  return {
    root: new Node(value),
    appendNode: function (value) {
      let head = checkNextNode(this.root);
      head.next = new Node(value);
      head.next.previous = head;
    },
    prependNode: function (value) {
      const temporal = this.root;
      this.root = new Node(value);
      this.root.next = temporal;
    },
    getHead: function () {
      return checkNextNode(this.root);
    },
    getTail: function () {
      return this.root;
    },
    size: function () {
      return Node.count;
    },
    pop: function() {
      let secondLast = checkNextNode(this.root).previous;
      secondLast.next = null;
    },
    contains: function(value){
      containsValue(this.root, value);
    },
    find: function(value){
     return valuePosition(this.root, value, 0);
    },
    ToString: function(){
      return printNodeValue(this.root);
    },
  };
}

【讨论】:

  • [更新] 围绕类的递归函数更改工厂对最终结果没有任何影响。
  • [更新] 我终于找到了这个错误。工厂返回部分中的 find 函数正在使用函数 valuePosition。这种嵌套使得无法获得结果,但其背后的原因是限制对 valuePosition 的计数和节点参数的访问。我已经尝试在我创建的测试类中使用 # 封装 valuePosition,但它更复杂。问题:我也是一名积极的 C++ 学习者,我是否对这两种语言的编码风格/语法感到困惑?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2012-08-10
  • 2020-01-22
  • 1970-01-01
相关资源
最近更新 更多