【问题标题】:Building symbol table using hash table使用哈希表构建符号表
【发布时间】:2011-09-05 06:52:37
【问题描述】:

我正在尝试使用哈希表构建符号表。总体思路是

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 }

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

你们有什么想法来实现这个比这更快的范围吗?它应该更快,因为我的实现比“他们提供的慢版本”要慢

非常感谢!

【问题讨论】:

    标签: c++ hash hashmap hashtable


    【解决方案1】:

    这是一个不错的主意。在大多数语言中,作用域很少嵌套得非常深,可能平均有 3 或 4 个嵌套作用域。所以我不会担心“很远很远”的事情,因为这些都是病态的情况。

    【讨论】:

    • 谢谢,但我需要担心,因为要测试这个程序的示波器有几百或几千个。
    • @Kelly 说什么?我从来没有,从来没有见过这样的事情。请记住,只要作用域处于活动状态,您就只能维护作用域。
    【解决方案2】:

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

    【讨论】:

    • 这会比我做的方法快吗??
    • @kelly-song 好吧,它应该会更快一些,因为您只在一个哈希表中搜索。在任何情况下,您都应该分析您的程序以查看瓶颈在哪里。
    • 对不起.. 我的程序是什么配置文件?和瓶颈?对这些东西不熟悉;p
    • @kelly-song Profiling 是指使用称为 profiler 的特殊工具来查找程序的执行时间特征(profile)。瓶颈是支配执行时间的代码片段,即程序在执行该片段上花费的时间比代码的任何其他部分都要多。
    【解决方案3】:

    当我这样做时,我将哈希表用于符号,而不是用于实体。 对于每个符号,我都有一个实体列表。每个实体在两个 列表,一个来自符号,第二个来自范围。名单 从符号像堆栈一样管理:当我访问一个符号时, 范围内的实体始终是列表中的第一个。当我离开瞄准镜时, 我浏览了它的实体列表,并将它们从列表中删除 符号。

    这是一段时间以前,在 STL 之前(甚至在 C++ 之前);一世 手动实现所有内容,并使用侵入式链接 列表,使用这样设计的算法,我可以删除一个元素 在不知道列表本身在哪里的情况下从列表中获取。 (这是 用手写的双链表相对容易。)今天,用 STL(以及访问位置的重要性),我可能只是 在每个实体中放置一个指向列表头部的指针。使用 STL,并且 考虑到地点,我可能会使用std::vector 作为列表 对于每个实体(符号表因此是 std::stringstd::vector)。符号表查找,一旦找到条目,很简单 在向量上调用back()(在检查它不为空之后,如果 当向量变为空时,您不会清除条目)。当你 创建新实体,在新范围内,在向量上调用 push_back, 并将向量的地址保存在范围的条目中(a std::stackstd::vector<std::vector<Entity>*>);离开时 范围,您遍历此堆栈顶部的向量,调用 pop_back 在其所有条目上,然后将其从堆栈中弹出。 (和 显然,当进入一个新的范围时,你 push 一个新的空向量到 范围堆栈。)

    维护双重列表意味着对于所有操作,你知道 准确访问哪个元素,而无需迭代 任何事物;永远无法访问一个实体来查看它是否是那个实体 您正在寻找。在我的日子里,这相当简单,但很多 代码,需要相当小心,我的实现可能 今天不会那么快,因为地方不好。今天,随着 STL,您需要更少的代码,并且通过使用std::vector 来处理所有 列表,你会得到更好的位置;你还是要小心 这样您就不会最终保存将失效的迭代器。 (但如上所述实现,您不需要;所有访问 总是到向量的最后一个元素,所以保存的地址 向量本身就足够了。当然,前提是你的哈希 实现不会移动向量。)

    【讨论】:

    • 嗨!像我这样的菜鸟似乎也可以接受。但我不太确定你所说的具有实体的符号是什么意思。我知道符号是,假设 (int i) i 是符号?但是列表实体是什么意思?到目前为止,我的猜测是哈希表中的每个项目,它存储符号和两个实体,它就像一个堆栈。其中一个来自当前范围,其他来自外部范围?谢谢你的详细信息!
    • @Kelly Song “Entity”,在这里,就是符号可以命名的任何东西。在您的示例中,变量,但在我的情况下,它也可以是函数,并且使用更复杂的语言、类型等。因此哈希图中的每个条目都有一个名称(符号,也充当索引),并且一个std::vector<Entity>,其中Entity 是符号定义的任何内容的表示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 2011-02-27
    • 2015-10-06
    • 1970-01-01
    相关资源
    最近更新 更多