使用哈希表建立符号表

时间:2011-05-31 07:54:49

标签: c++ hash hashmap hashtable

我正在尝试使用哈希表构建符号表。一般的想法是

int alpha;
2 int beta;
3 alpha = 0; // the alpha declared in line 1
4 beta = 0; // the beta declared in line 2
5 gamma = 0; // Error! gamma hasn't been declared.
6 {
7 int beta; // This beta shadows the one declared in line 2.
8 int gamma;
9 alpha = 0; // the alpha declared in line 1
10 beta = 0; // the beta declared in line 7
11 gamma = 0; // the gamma declared in line 8
12 }

等等。您只能使用向量,列表,堆栈和队列库,并尝试尽可能快地创建它。 我的想法是在每个范围内,我在列表中声明哈希表并将所有信息保存到该表中,每当我有新范围时,我将新哈希表推入列表中。 但是当程序正在寻找远远超出范围的项目时,似乎这种方法非常慢,因为你必须寻找每个范围才能找到该项目。

你们有没有想过要比这更快地实现这个范围?它应该更快,因为我的实现比他们提供的“慢版本”慢

非常感谢!

3 个答案:

答案 0 :(得分:1)

只有一个哈希表用于所有内容,以及一堆上下文对象。每当看到“{”时,在堆栈上推送一个新对象。隐藏变量时,请记住上下文对象中的旧符号,并在哈希表中覆盖它。当您看到'}'并弹出上下文时,请恢复您在那里记住的符号。

答案 1 :(得分:1)

当我这样做时,我使用哈希表作为符号,而不是实体。 对于每个符号,我都有一个实体列表。每个实体都是两个 列表,一个来自符号,另一个来自范围。列表 从符号管理就像一个堆栈:当我访问一个符号时, 范围内的实体始终是列表中的第一个。当我离开范围时, 我走了它的实体列表,并将它们从列表中删除 符号。

这是前一段时间,在STL之前(甚至在C ++之前);一世 手工实施所有东西,并使用侵入性链接 列表,使用如此设计的算法,我可以删除一个元素 从列表中不知道列表本身在哪里。 (这是 用手写的双链表比较容易。)今天用的 STL(以及访问地点的重要性),我可能只是简单地说 在每个实体中放置一个指向列表头部的指针。随着STL,和 对于地点的考虑,我可能会使用std::vector作为列表 对于每个实体(符号表因此是std::string的映射 std::vector)。一旦找到条目,符号表查找就很简单了 在向量上调用back()(在检查它不为空之后,如果 当向量变空时,不要清除条目。当你 创建新实体,在新范围内,您在向量上调用push_back, 并将范围的地址保存在范围的条目中(a std::stack的{​​{1}};离开的时候 范围,你遍历这个堆栈顶部的向量,调用 std::vector<std::vector<Entity>*>在其所有条目上,然后将其从堆栈中弹出。 (和 很明显,当你输入一个新的范围时,你pop_back一个新的空矢量 范围堆栈。)

维护双重列表意味着对于所有操作,您知道 究竟要访问哪个元素,而不必迭代 任何事情;从来没有任何实体可以访问实体,看它是否是那个实体 您正在寻找。在我的日子里,这很简单,但很多 代码,需要相当小心,我的实现可能 今天不会那么快,因为地方不好。今天,随着 STL,你需要更少的代码,并使用push来完成所有的代码 列表,你会得到稍微好一点的地方;你还是要小心点 这样你就不会最终保存将失效的迭代器。 (但如上所述实现,您不需要;所有访问 总是到向量的最后一个元素,所以保存地址 矢量本身就足够了。当然,提供了你的哈希值 实现不会移动向量。)

答案 2 :(得分:0)

这是一个好主意。在大多数语言中,范围很少嵌套得很深,可能是平均3或4个嵌套范围。因此,我不会担心“远,远”的事情,因为这些将是病态的案例。