- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当提供字符串输入时,我被困在如何生成树的逻辑上。例如当我有以下形式的输入时 -
(1 (2 (3) (4)) (5 (6) ())
表示树会像这样-
1
/ \
2 5
/ \ /\
3 4 6 ()
我可以像 tree.add(data) 这样从平常构建树,然后通过判断它是否大于或小于父节点来寻找要自添加的新节点。但是我无法理解如何实现如何以二进制数据结构形式存储上述字符串。
这是我到目前为止尝试过的 -
public class BinaryTree {
static Node root;
public static void levelorder(Node<?> n) {
Queue<Node<?>> nodequeue = new LinkedList<Node<?>>();
if (n != null)
nodequeue.add(n);
while (!nodequeue.isEmpty()) {
Node<?> next = nodequeue.remove();
System.out.print(next.data + " ");
if (next.getLeft() != null) {
nodequeue.add(next.getLeft());
}
if (next.getRight() != null) {
nodequeue.add(next.getRight());
}
}
}
private static String[] breakString(String elements) {
int indexOfOpenBracket = elements.indexOf("(");
int indexOfLastBracket = elements.lastIndexOf(")");
String removedPString = elements.substring(indexOfOpenBracket + 1,
indexOfLastBracket);
String[] breakRemovedPString = removedPString.split(" ");
if (breakRemovedPString[1].contains("(")) {
add(breakRemovedPString[0], breakRemovedPString[1], breakRemovedPString[2]);
}
return breakRemovedPString;
}
static void add(String parent, String leftString, String rightString) {
Node<String> nodeToAdd = new Node<String>(parent);
if (root == null) {
root = nodeToAdd;
root.left = new Node<String>(leftString);
root.right = new Node<String>(rightString);
} else {
}
}
public static void main(final String[] args) {
String treeString = "(1 (2) (3))";
breakString(treeString);
levelorder(root);
System.out.println();
}
}
请针对此问题提出一些实现建议。
最佳答案
这是一个经典的解析问题。最简单的方法可能是递归下降。这是树语言的语法:
T -> ( number T T )
| ( number )
| ()
要将其转换为解析器,我们可以通过形式化转换为 LL(1) 形式,然后进行编码。我会让您继续阅读并展示结果。
package treereader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Reader;
enum Token { LPAREN, RPAREN, NUMBER, EOF, ERROR };
class Scanner {
final Reader in;
final char [] buf = new char[1];
final StringBuilder token = new StringBuilder();
private static final char EOF_MARK = Character.MIN_VALUE;
Scanner(Reader in) {
this.in = in;
read();
}
final void read() {
try {
if (in.read(buf) < 1) {
buf[0] = EOF_MARK;
}
} catch (IOException ex) {
System.err.println("i/o error");
buf[0] = EOF_MARK;
}
}
Token getNext() {
while (Character.isWhitespace(buf[0])) {
read();
}
if (Character.isDigit(buf[0])) {
token.setLength(0);
do {
token.append(buf[0]);
read();
} while (Character.isDigit(buf[0]));
return Token.NUMBER;
}
if (buf[0] == '(') {
read();
return Token.LPAREN;
}
if (buf[0] == ')') {
read();
return Token.RPAREN;
}
if (buf[0] == EOF_MARK) {
return Token.EOF;
}
return Token.ERROR;
}
String getString() {
return token.toString();
}
}
class Node {
public void print(PrintStream out) {
out.print("()");
}
}
class UnaryNode extends Node {
int val;
public UnaryNode(int val) {
this.val = val;
}
@Override
public void print(PrintStream out) {
out.print("(" + val + ")");
}
}
class BinaryNode extends Node {
int val;
Node left, right;
public BinaryNode(int val, Node left, Node right) {
this.val = val;
this.left = left;
this.right = right;
}
@Override
public void print(PrintStream out) {
out.print("(" + val + " ");
left.print(out);
out.print(' ');
right.print(out);
out.print(')');
}
}
class Parser {
final Scanner scanner;
Token lookAhead;
Parser(Reader in) {
scanner = new Scanner(in);
lookAhead = scanner.getNext();
}
void advance() {
lookAhead = scanner.getNext();
}
void match(Token token) throws IOException {
if (lookAhead == token) {
advance();
} else {
throw new IOException("Expected " + token + ", found " + lookAhead);
}
}
Node parse() throws IOException {
Node tree;
match(Token.LPAREN);
if (lookAhead == Token.NUMBER) {
int val = Integer.valueOf(scanner.getString());
advance();
if (lookAhead == Token.LPAREN) {
Node left = parse();
Node right = parse();
tree = new BinaryNode(val, left, right);
} else {
tree = new UnaryNode(val);
}
} else {
tree = new Node();
}
match(Token.RPAREN);
return tree;
}
}
public class TreeReader {
public static void main(String[] args) {
try {
Parser parser = new Parser(new BufferedReader(new FileReader(new File(args[0]))));
Node tree = parser.parse();
tree.print(System.out);
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
关于java - 从字符串输入构建树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25588041/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!