【发布时间】:2011-04-04 15:55:43
【问题描述】:
我无意中让我的学生过度限制了用于解决以下问题的共享课程。我意识到这可能是该网站的居民可能会喜欢的问题。
第一个团队/函数 getNodes 使用带符号整数和四个操作 +、-、* 和 / 获取一个表示前缀表达式的字符串,并使用类 Node 生成相应的以空结尾的令牌链表,其中通过“右”指针链接的标记。
第二个团队/函数 getTree 采用类似的字符串,将其传递给 getNodes,并将结果节点重新链接为表达式树。
第三个团队/函数,evaluate,接受一个类似的字符串,将其传递给 getTree,并评估结果表达式树以形成答案。
紧随其后的是过度约束的 exptree.h。这个问题必须通过只写上面定义的三个函数来解决,没有额外的函数。
#ifndef EXPTREE_H_
#define EXPTREE_H_
using namespace std;
enum Ops{ADD, SUB, MUL, DIV, NUM};
class Node {
private:
int num;
Ops op;
Node *left, *right;
public:
friend Node *getNodes(string d);
friend Node *getTree(string d);
friend int evaluate (string);
};
int evaluate(string d);
Node *getNodes(string d);
Node *getTree(string d);
#endif
可以使用的库只有这些
#include <iostream>
#include <vector>
#include <string>
#include "exptree.h"
对于那些担心我的学生的人,我今天要指出的是,只需几个更合适的函数就可以轻松解决这个问题。我知道表达式树可以编码有理数而不仅仅是整数。我今天也会指出这一点。
这是我根据他们的规格给他们的驱动程序。
#include <iostream>
#include <string>
#include "exptree.h"
using namespace std;
void test(string s, int target) {
int result = evaluate(s);
if (result == target)
cout << s << " correctly evaluates to " << target << endl;
else
cout << s << "(" << result
<< ") incorrectly evaluates to " << target << endl;
}
int main() {
test("42", 42);
test("* - / 4 2 1 42", 42);
test("* - / -4 +2 -1 2", -2);
test("* - / -4 +2 -1 2 ", -2);
test("* 9 6", 54);
return 0;
}
您能否以尽可能优雅的方式编写这三个函数来解决这个噩梦般的问题?
【问题讨论】:
-
大约一年前,我在我的一个课程中解决了同样的问题(我敢打赌每个人都有)。我们通过使评估多态来解决它。乘节点将它们的左右相乘,值节点将简单地返回它们的值,依此类推。使程序自行编写:) 我意识到这违反了您的“只写三个函数”的约束,但将它们介绍给它们可能会很有趣。
-
令牌是否保证像您的示例中那样以空格分隔?
-
“唯一可以使用的库是这些”
<string>?否则很难定义函数;-) -
-1:答案必须编译吗?驱动程序不会。当
exptree.h包含在驱动程序中时,exptree.h中的string已不在全局命名空间中。 -
@rob 哇,唯一的问题是包括
<string>和using namespace std或前缀strings。有什么大不了的?
标签: c++ expression-trees friend