弄清楚这段代码的内容(递归下降案例研究)

时间:2018-06-29 23:05:13

标签: c++ iterator stl-algorithm

我正在阅读一本《数据结构和算法》书,并且有一个关于递归的案例研究,特别是使用递归下降的解析器。我对C ++有点陌生(我正在一边学习Stanley B. Lippman的C ++ Primer第5版,一边学习它。)

我在代码上有些卡住,并试图理解它。我在最下面写的内容(项目符号)是否准确描述了函数中发生的事情?我会发布标头,但是它太长了,如果您搜索“数据结构”,则可能可以在线找到它 Adam Drozdek编写的C ++语言和算法-interpreter.h”。

double Statement::findValue(char* id) {
    IdNode tmp(id);
    list<IdNode>::iterator i = find(idList.begin(), idList.end(), tmp);
    if (i != idList.end())
        return i->value;
    else
        issueError("Unknown variable");
    return 0;
}

void Statement::processNode(char* id, double e) {
    IdNode tmp(id, e);
    list<IdNode>::iterator i = find(idList.begin(), idList.end(), tmp);
    if (i != idList.end())
        i->value = e;
    else
        idList.push_front(tmp);
}

findValue()

  • 寻找某个变量的值
  • 使用迭代器i以便遍历列表
  • 使用find()查找tmp
  • 如果我不等于列表末尾的值,请返回
  • 否则,找不到变量

processNode()

  • 使用迭代器i来处理节点
  • 寻找与tmp匹配的变量
  • 查找变量并将其值设置为e的值
  • 否则,将变量存储到idList上以便以后评估

2 个答案:

答案 0 :(得分:0)

您的理解基本上是正确的。我将逐条描述 更为精确的术语。

double Statement::findValue(char* id) {
    IdNode tmp(id);

这会使用传入的字符串构造一个名为tmp的变量。(好吧,我假设id是一个字符串。在C语言中,通常将指针传递到以零结尾的开头要传递字符串时的字符数组。在C ++中,相同的事情很常见,但是现在由于我们在标准库中有更好的字符串和范围类型而变得不那么普遍了。但是并不是每个char *都是一个字符串。它可能只是指向单个字符的指针。尽管如此,上下文的强力提示它是一个字符串。)

    list<IdNode>::iterator i = find(idList.begin(), idList.end(), tmp);

使用std::find算法搜索从idList的开头到结尾的元素范围,以查找等于tmp的元素。

请注意idList.end()是一个迭代器,它指示列表的实际结尾而不是列表的最后一项。您可以将其视为列表中最后一个元素之外的一个元素。 C和C ++中的迭代器范围(和数组索引)通常包含第一个值,并且不包含第二个值。因此find将从第一个元素开始,然后继续(但不贯穿列表的末尾)。

这里没有显示,但是我假设operator==(const idNode &, const idNode &)有一个重载,如果两个idNodes的名称匹配,则返回true,而不管值字段是否匹配。

如果范围内没有匹配项,则std::find将返回结束迭代器。如果存在匹配项,它将返回引用匹配元素的迭代器。所以...

    if (i != idList.end())
        return i->value;
    else
      issueError("Unknown variable");

这将返回匹配的值字段(如果有),或者如果没有则调用issueError

    return 0;
}

在后一种情况下,假设issueError返回并且没有终止程序或引发异常,则该函数将返回值0(由于返回类型为double,因此该值将被隐式转换到0.0)。

processNode几乎相同,除了它在找到的节点中设置值而不是返回值。

答案 1 :(得分:0)

定义一个函数,该函数接受一个指向char的指针(可能是一个数组)并返回一个double

double Statement::findValue(char* id) {

基于该指针,创建类型为IdNode的临时(将在“返回”时死亡):

IdNode tmp(id);

使用一个(std::,但可以是具有相同功能的任何函数)函数,该函数在容器tmp中查找idList。结果是一个插入器i,其类型必须与容器使用的类型相同:

list<IdNode>::iterator i = find(idList.begin(), idList.end(), tmp);

检查是否找到了东西。 idList.end()的意思是“超越终点”,超出容器中的最后一项:

if (i != idList.end())

返回找到的项目的成员value(属于IdNode的成员)。如果value不是double,请转换为它。

    return i->value;

否则,请调用issueError函数。

else
    issueError("Unknown variable");

退出函数,返回值为{= 0的double

return 0;
}

相同,但是:此函数接受两个参数,但不返回任何内容:

void Statement::processNode(char* id, double e) {

相同,但是:IdNode构造函数使用两个参数:

IdNode tmp(id, e);

相同

list<IdNode>::iterator i = find(idList.begin(), idList.end(), tmp);

相同

if (i != idList.end())

现在,修改找到的项目。只需更新value成员:

    i->value = e;

否则,添加 tmp,将其插入idList容器的开头。

else
    idList.push_front(tmp);

退出功能:

}