为括号串构建一个树
Build a tree for string of parentheses
我有一个
typedef struct node
{
node* br;
node* son;
};
给定由(
、)
的序列组成的字符串char* str
我需要为这个字符串构建一个树,例如:对于字符串(()())(),将构建以下树:
br br
node ----- node ---- NULL
|son |son
| NULL
| br br br
node --- node --- node --- NULL
|son |son
NULL NULL
您的树有点难以阅读。我假设每个括号都是一个节点,所有嵌套的括号都是子节点。
这里有一个简单的算法:
We start with a root node representing the empty string.
For each char c in the string s:
if c == '(':
create a new child node
move to the new created node
else:
move to the parent node
这会给你一棵好看的树。Ofc您必须检查字符串是否有效,并在需要时进行补偿/更正。
此代码使用堆栈来存储与尚未看到闭合paren的打开paren相对应的节点。当它看到一个打开的paren时,它会将一个新节点推送到堆栈中。当它看到一个闭合的paren时,它会从堆栈中删除当前的顶部节点,并使其成为其父节点的子节点,父节点就是它下面的节点。
#include <list>
#include <stack>
#include <functional>
#include <iostream>
struct Node {
std::list<Node> children;
};
bool parse_parens (const char *str, Node *out)
{
// stack of nodes for which open paren was seen but
// close paren has not yet been seen
std::stack<Node> stack;
// push the virtual root node which doesn't correspond
// to any parens
stack.push(Node());
for (size_t i = 0; str[i]; i++) {
if (str[i] == '(') {
// push new node to stack
stack.push(Node());
}
else if (str[i] == ')') {
if (stack.size() <= 1) {
// too many close parens
// (<=1 because root has no close paren)
return false;
}
// Current top node on stack was created from the
// open paren which corresponds to the close paren
// we've just seen. Remove this node it from the stack.
Node top = std::move(stack.top());
stack.pop();
// Make it a child of the node which was just below it.
stack.top().children.push_back(std::move(top));
}
else {
// bad character
return false;
}
}
if (stack.size() > 1) {
// missing close parens
return false;
}
// return the root node
*out = std::move(stack.top());
return true;
}
bool print_parens (const Node &node)
{
for (std::list<Node>::const_iterator it = node.children.begin(); it != node.children.end(); ++it) {
const Node &child = *it;
std::cout << "(";
print_parens(child);
std::cout << ")";
}
}
int main ()
{
Node root;
bool res = parse_parens("(())()(()())", &root);
if (!res) {
std::cout << "Error parsing!n";
return 1;
}
print_parens(root);
std::cout << "n";
return 0;
}
这使用std::list
来存储同级节点,这比您提出的更容易使用。然而,同样的算法也应该在那里工作。
您可以使用stack来实现这一点,找到左括号后,将此节点添加到stack中。如果再次使用左括号,则将子元素添加到堆栈的最顶端元素。在右括号中,从堆栈中删除节点。就是这样。
相关文章:
- 函数向量_指针有不同的原型,我可以构建一个吗
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 构建一个由C和C++文件组成的库
- 如何使用 samtools C API 构建一个简单的主.cpp文件
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 在Qt/C++中从一个代码构建两个略有不同的项目
- 如何构建一个 setup.py 来编译C++使用 Python、pybind11 和 Mingw-w64 的扩展?
- 如何构建一个异常类来报告C++中的哪些文件和行号?
- 在 Visual Studio 中构建一个没有 C/C++ 运行时的静态库
- 创建一个类来访问和指定向量类型,并构建一个获取位置并为其分配区域的类
- 下一个云桌面客户端构建过程
- 将vector<vector<double>>从x86平台中创建的一个进程发送到x64中构建的另一个进程的最快方法是什么
- cmake在构建过程中使用另一个工具检测标志
- 使用步骤c++构建一个向量
- 如何制作一个根据拉取请求关闭和打开功能的构建系统?
- 为什么它无法在 c++ 中全局声明一个构建为 dll 文件的类?
- 为什么我们需要构建一个提升库,仅仅包含头文件还不够吗,因为提升是模板
- 我正在尝试构建一个简单的程序来从 mysql 数据库中读取信息
- 可视化合并一个vc++和一个c++构建器项目
- 创建一个构建框架来支持编译支持多个平台的代码