在树结构.txt文件中搜索节点

Searching a node in tree structure .txt file

本文关键字:搜索 节点 文件 txt 结构      更新时间:2023-10-16

我有一个树结构的.txt文件,看起来像这样:

R  R1   1        "Template for setting parameters"  ENGLISH        1                      1
U U1    "Any user"   ENGLISH   100%      1
A A1   "Setup stim levels" 0min          0           0%           AVAILABLE FALSE FALSE TRUE TRUE
B SA1 1 "Engine tests"
M CH1 1 1 120mA 10us 450us 40Hz ASYM "Channel 1"
M CH2 1 2 120mA 10us 450us 40Hz ASYM "Channel 2"
M CH3 1 3 120mA 10us 450us 40Hz ASYM "Channel 3"
P P0 "Phase zero" 0ms NONE 2000ms STOP STOP STOP   
O CH1 0mA  0ms    0ms   600000ns 180us RATE
O CH2 0mA  0ms    0ms   600000ns 180us RATE
O CH3 0mA  0ms    0ms   600000ns 180us RATE
P P1 "Phase one" 0ms NONE 2000ms STOP STOP STOP  
O CH1 0mA  0ms    0ms   600000ns 180us RATE
O CH2 0mA  0ms    0ms   600000ns 180us RATE
O CH3 0mA  0ms    0ms   600000ns 180us RATE

@--------

在这里,每个节点只有一个父节点,它的引用在其兄弟姐妹中是唯一的(例如P0P1等(

我可以通过按如下方式拆分行来搜索子项中的值(查找以"O CH"开头的行(:

QString filename = "config_keygrip";
QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
QFile originalFile(path);
originalFile.open(QIODevice::ReadOnly | QIODevice::Text); 
while (!originalFile.atEnd()) {
QByteArray line = originalFile.readLine();
if (line.contains("O CH")) {
QStringList list = QString::fromUtf8(line).split(' ', QString::SkipEmptyParts);
qDebug()<<"Extracted values are: "<< list[1]<< list[2]<<list[3]<< list[4]<< list[5]<<"and"<<list[6];
}
}
originalFile.close();

上面的代码为我提供了所有子项的值。

我有点卡在如何搜索特定节点的子节点上。

例如。通过单击名为NEXTpushButton如何逐个进入节点并提取子值(如上所述(?

注意:我假设缩进在这里很重要,即孩子比他们的父母缩进更多。它还假定嵌套级别正好相隔一个空间。

让我们从一个简单的Node结构开始:

struct Node {
Node * parent;
char tag;
QString reference;
QString full_line;
QVector<Node *> children;
};

首先,编写一个处理一行并返回std::optional<std::pair<int, Node*>>的函数。这将返回一个空值(如果该行上没有可读取的内容(或一对(缩进级别,新节点(。

std::optional<std::pair<int, Node*>> process_line(QString line) {
int indentation = 0;
while (line.size() > indentation && line[indentation] == ' ') {
indentation++;
}
line = line.mid(indentation);
if (line.isEmpty())
return std::nullopt; // This line only contains spaces, return nothing.
Node * ret = new Node;
ret->parent = nullptr;
QTextStream ts(&line);
ts >> ret->tag >> ret->reference;
ret->full_line = line;
return std::make_pair(indentation, ret);
}

然后创建一个循环来处理文件的每一行。 跟踪Node *元素的堆栈,该堆栈最初只是根节点。 对于文件中的每一行,将其传递给read_line并实现以下逻辑:

  • 如果read_line返回nullopt:什么都不做。
  • 否则,根据当前节点堆栈检查返回对的缩进级别:
    • 如果indentation == nodes.size() - 1:这是当前顶部节点的子节点。设置new_node->parent = nodes.top()nodes.top()->children.push_back(new_node)。将new_node推送到节点堆栈上。
    • 如果indentation < nodes.size() - 1:弹出nodes直到indentation == nodes.size() - 1,然后按上述操作。

您现在有一棵树,您可以在其中向下(通过children(和向上(parent(导航。