javascript - 递归连接传递的字符串
问题描述
我正在用 JS 编写 BST,并尝试将传递给成员函数的字符串连接起来但没有成功。console.log()
有效,但它会自动为每个条目开始一个新行。
"use strict";
class Node {
constructor(dt) {
this.data = dt;
this.left = null;
this.right = null;
}
}
class BST {
constructor() {
this.root = null;
}
insert(parent, key) {
if (!this.root) return this.root = new Node(key);
else {
if (key < parent.data) {
if (!parent.left) {
parent.left = new Node(key);
} else {
this.insert(parent.left, key);
}
} else if (key > parent.data) {
if (!parent.right) {
parent.right = new Node(key);
} else {
this.insert(parent.right, key);
}
}
}
}
// Doesn't work
printIN(parent, string) {
if (parent) {
this.printIN(parent.left);
console.log(parent.data);
string += " " + parent.data;
// return string += " " + parent.data;
this.printIN(parent.right);
}
return string;
}
// This works.
// printIN(parent) {
// if (parent) {
// this.printIN(parent.left);
// console.log(parent.data);
// this.printIN(parent.right);
// }
// }
}
let treeA = new BST();
let tree = null;
tree = treeA.insert(treeA.root, 5);
tree = treeA.insert(treeA.root, 7);
tree = treeA.insert(treeA.root, 3);
tree = treeA.insert(treeA.root, 14);
let string = [""];
string = treeA.printIN(treeA.root, string);
console.log();
console.log(string);
// treeA.printIN(treeA.root);
我想在一行上打印出数字,而不是每次都从新行开始。我认为使用字符串连接是合乎逻辑的解决方案,但我似乎无法使其工作。
// Doesn't work
printIN(parent, string) {
if (parent) {
this.printIN(parent.left);
console.log(parent.data);
string += " " + parent.data;
// return string += " " + parent.data;
this.printIN(parent.right);
}
return string;
解决方案
另一个答案为您提供了字符串问题的解决方案。下面的代码片段有一个替代方案。但更重要的是,它为您的 OOP 方法提供了一些重要的清理。
有两个主要原因是必要的。
首先,您有对象的成员函数,它们仍然需要将对象传递给它们。这是多余和令人困惑的。任何不引用的 OOP 函数都this
应该是静态函数。但是,如果您要进行 OOP(实际上我可能会反对),那么您不应该像使用方法一样使用静态函数。因此insert
,printIN
不应该有parent
参数。
其次,您正在处理递归结构。树的节点应该与树本身具有相同的设计。这使各种事情变得更容易。但是你有一个类Node
和一个叫BST
. 然后BST
有一个root
节点,它应该是递归的。我看不出有什么理由。BST 本质上是一个根节点,具有一个data
值(通常,尽管我们可以像您一样将其设为可选)并且可能left
和right
节点本身就是 BST。
将代码修复为像这样工作可以大大简化它。这是一种实现:
class BST {
constructor(data) {
this.data = data;
}
insert(key) {
if (!this.data) {
this.data = key;
} else {
if (key < this.data) {
if (!this.left) {
this.left = new BST(key);
} else {
this.left.insert(key);
}
} else if (key > this.data) {
if (!this.right) {
this.right = new BST(key);
} else {
this.right.insert(key);
}
}
}
}
printIN() {
return (this.left ? this.left.printIN() + ' ' : '') +
this.data +
(this.right ? ' ' + this.right.printIN() : '');
}
}
let treeA = new BST();
treeA.insert(5);
treeA.insert(7);
treeA.insert(3);
treeA.insert(14);
console.log(treeA.printIN());
这里没有Node
课。一切都在BST
. 此外,BST
对象不需要root
节点,方法更简单。
我会注意到,尽管这printIN
比我们可以以相同方式使用的另一个函数有用:
toArray() {
return [
...(this.left ? this.left.toArray() : []),
this.data,
...(this.right ? this.right.toArray() : [])
];
}
这将允许
console.log(treeA.toArray()); //=> [3, 5, 7, 14]
你可以通过join
使用空格来获取你的字符串。这个功能让我觉得比你拥有的 printIN 更有用。
我们还可以添加一个静态函数:
static fromArray(xs) {
return xs .reduce (function (tree, x) {
tree.insert(x)
return tree
}, new BST())
}
这将允许我们写
tree = BST .fromArray ([8, 6, 7, 5, 3, 0, 9]);
tree .printIN() //=> [0, 3, 5, 6, 7, 8, 9]
我提到我什至不会用 OOP 来做这件事。但是这些天我并没有做太多那样的事情,更喜欢功能性方法。所以,如果你很好奇,这里有另一个完全解决这个问题的方法,只使用函数和在你执行 时没有修改的树insert
,而是返回新的树:
const bst = (xs) =>
xs .reduce ((tree, x) => bstInsert (x, tree), {})
const bstInsert = (x, {left, data, right} = {}) =>
data == undefined
? {data: x}
: x < data
? {data, left: bstInsert (x, left), ...(right ? {right} : {})}
: {data, ...(left ? {left} : {}), right: bstInsert (x, right)}
const inorder = ({left, data, right} = {}) => [
...(left ? inorder(left) : []),
data,
...(right ? inorder(right) : [])
]
inorder (bst ([8, 6, 7, 5, 3, 0, 9])) //=> [0, 3, 5, 6, 7, 8, 9]
我不特别推荐这种技术,但 FP 可以成为 OOP 的强大替代方案。
推荐阅读
- java - 如何在我们使用 Retrofit 上传文件时设置进度条。我需要进度条数 100
- javascript - 根据单击的项目启用/禁用子组件内的 this.props.children
- groovy - groovy 脚本在 nifi executescript 处理器中不起作用
- java - cron 调度程序在调度程序的预定时间被调用两次
- qt - 编译 Qt qbs 生成的 Visual Studio 解决方案时出错
- asp.net-mvc - Azure 门户中的应用程序设置未覆盖通用值
- java - Spring Boot Oauth2 对同一个 URL 使用多个 grant_types
- sql - 大型 MSSQL 数据库上的字符串列索引
- git - 没有开发分支的 git 策略是否有名称?
- github - 如何在我的主分支中上传修改文件