You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS字符串转树形结构出现节点重复打印问题求助

树形结构解析重复打印问题排查

我编写了一段JavaScript代码,用于将字符串"(1 (2 (4 5 6 (7) 108 (9)) 3))"解析为TreeNode树形结构,但运行后发现带有子节点的节点会被重复打印。

代码实现

// 输入字符串
const input = "(1 (2 (4 5 6 (7) 108 (9)) 3))";

class TreeNode {
  constructor(value) {
    this.value = value;
    this.children = [];
  }
}

function parseInput(input) {
  let root = null;
  let current = null;
  const stack = [];

  for (let i = 0; i < input.length; i++) {
    const char = input[i];

    if (char === '(') {
      if (current !== null) {
        const newNode = new TreeNode(current);
        if (stack.length > 0) {
          stack[stack.length - 1].children.push(newNode);
        } else {
          root = newNode;
        }
        stack.push(newNode);
        current = null;
      }
    } else if (char === ')') {
      stack.pop();
    } else if (char !== ' ' && char !== '\n') {
      let numStr = char;
      while (i + 1 < input.length && /\d/.test(input[i + 1])) {
        numStr += input[++i];
      }
      const newNode = new TreeNode(parseInt(numStr));
      if (stack.length > 0) {
        stack[stack.length - 1].children.push(newNode);
      } else {
        root = newNode;
      }
      current = newNode.value;
    }
  }

  return root;
}

// 打印树形结构的函数
function printTree(node, depth = 0) {
  const indent = '  '.repeat(depth);
  console.log(`${indent}value: ${node.value}`);
  if (node.children.length > 0) {
    console.log(`${indent}children: [`);
    node.children.forEach((child) => printTree(child, depth + 1));
    console.log(`${indent}]`);
  }
}

const parsed = parseInput(input);
console.log(printTree(parsed));

当前错误输出

value: 1
children: [
  value: 2
  value: 2
  children: [
    value: 4
    value: 5
    value: 6
    value: 6
    children: [
      value: 7
    ]
    value: 108
    value: 108
    children: [
      value: 9
    ]
  ]
  value: 3
]

期望输出

value: 1
children: [
  value: 2
  children: [
    value: 4
    value: 5
    value: 6
    children: [
      value: 7
    ]
    value: 108
    children: [
      value: 9
    ]
  ]
  value: 3
]

我只剩一个多小时就要提交代码了,请至少给我一个问题排查的提示!我已经尝试过调整代码、注释代码、咨询AI、搜索网络等方法。


排查提示

问题核心是parseInput函数重复创建并添加了相同value的节点:

  • 以节点2为例:解析数字2时,代码会创建节点2并添加到父节点(节点1)的children中;随后遇到(时,又用current中存储的2值,再次创建一个节点2并添加到节点1的children里,最终导致重复打印。
  • 修正方向:调整节点创建逻辑,让每个节点只被创建并添加一次。正确流程应为:
    1. 遇到(时,标记即将创建一个带子节点的父节点;
    2. 解析数字时,创建对应节点:若当前是标记的父节点,则将其压入栈(用于后续添加子节点);若为叶子节点,仅添加到父节点children即可;
    3. 遇到)时,弹出栈顶节点(表示该节点的子节点解析完成)。

参考修正后的核心逻辑片段:

function parseInput(input) {
  let root = null;
  const stack = [];
  let isNewParent = false; // 标记是否要创建带子节点的父节点

  for (let i = 0; i < input.length; i++) {
    const char = input[i];

    if (char === '(') {
      isNewParent = true;
    } else if (char === ')') {
      stack.length > 0 && stack.pop();
    } else if (char !== ' ' && char !== '\n') {
      let numStr = char;
      while (i + 1 < input.length && /\d/.test(input[i + 1])) {
        numStr += input[++i];
      }
      const newNode = new TreeNode(parseInt(numStr));
      // 添加节点到父节点children
      stack.length ? stack[stack.length - 1].children.push(newNode) : root = newNode;
      // 如果是父节点,压入栈
      if (isNewParent) {
        stack.push(newNode);
        isNewParent = false;
      }
    }
  }
  return root;
}

内容的提问来源于stack exchange,提问作者IJustStartedLearningCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:44:49