【问题标题】:Implementation of a hash table in SWI-Prolog在 SWI-Prolog 中实现哈希表
【发布时间】:2019-04-22 22:50:12
【问题描述】:

所以我必须实现一个 ADT,在本例中是一个 SWI-Prolog 中的哈希表。 我需要帮助,因为我是这种编程语言的新手,不知道如何开始。

这开始是在 python(3) 中的一个实现,我在其中定义了一个类并添加了要使用的函数(add、is_empty?、delete、rehash、hash 等)。 但是现在,我需要在 prolog 中做一些类似的事情。

我访问过其他一些与我类似的stackoverflow问题,但我仍然无能为力。

我希望定义一个基本的哈希表,并能够添加键+值数据和其他一些基本功能。我不太确定这是否已经在其他地方实施。 请帮忙。

【问题讨论】:

  • @GuyCoder 这听起来是个非常糟糕的主意。它与哈希表相反。
  • 在缺乏破坏性赋值和直接内存操作的语言中,通常使用平衡树来实现键值映射而不是哈希表。像setarg/3 这样的语言操作通常是危险的,或者至少是不标准的。平衡树与哈希表具有不同的时间和空间复杂性,但真正的哈希表通常会破坏单赋值变量的持久性,如果它们不这样做,您通常不会获得您认为获得的性能属性。
  • @DanielLyons 当然可以。看我的回答。它将具有您期望的哈希映射的属性。 setarg/3 是可回溯的,所以它没有你说的那么糟糕。绝对比断言和收回更好,即使这会给你一个真正的哈希表。在 Prolog 中很容易为哈希映射数据结构提出特定的用例。这里真正的问题是我们还没有用例,因此不可能特别讨论任何方法的优缺点。

标签: python prolog swi-prolog abstract-data-type


【解决方案1】:

几个 Prolog 系统提供术语哈希内置或库谓词。例如,SWI-Prolog 提供了term_hash/2term_hash/4 内置谓词。这些谓词通常与第一个参数索引结合使用。一个简单的例子:

% dynamic predicate to hold hash table entries
% with the term hash used as first argument to
% take advantage of first-argument indexing
%
% hash_table(Hash, Term).
:- dynamic(hash_table/2).

add_hash_table_entry(Term) :-
    nonvar(Term),
    term_hash(Term, Hash),      % or term_hash/4
    assertz(hash_table(Hash, Term)).

del_hash_table_entry(Term) :-
    nonvar(Term),
    term_hash(Term, Hash),  % or term_hash/4
    retractall(hash_table(Hash, _)).

hash_table_entry(Term) :-
    (   var(Term) ->
        hash_table(_, Term) 
    ;   term_hash(Term, Hash),  % or term_hash/4
        hash_table(Hash, Term)
    ). 

【讨论】:

  • 但是你真的必须做这一切吗?如果你只是断言,那不会给你一个以第一个参数作为键的哈希表吗?哈希值本身无法访问,但这有关系吗?
  • @User9213 这取决于您所断言的复合术语的第一个参数是可索引的,还是以对常见访问模式有用的方式可索引的。它还取决于您是否将通过第一个参数、其他一些参数或一些可变的参数组合来访问这些术语。哈希表可以提供您在索引中可能没有的性能保证。但只有在具体案例中进行试验和测量才能告诉您哈希表是否是最佳解决方案。
【解决方案2】:

这听起来像是一个错误的想法。这个“哈希表”将如何使用?您期望不同的操作具有什么样的算法复杂度?为什么要实现一个不需要用户实现哈希表的语言的哈希表?

唯一合适的方法是对表使用一个扁平术语,每个桶一个参数。如果您有 k 个存储桶,那么您可以使用具有该元数 k 的术语,因此对于 256 个存储桶,您会得到 hash_table/256

empty_hash_table(T) :-
    length(Buckets, 256),
    maplist(=(nil), Buckets),
    T =.. [hash_table|Buckets].

您现在可以使用arg/3 在恒定时间内获取存储桶。您可以使用setarg/3 更改它们。

但这一切开始听起来很可疑。你需要更好地解释你的理由。为什么要在 Prolog 中实现哈希表?怎么用?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2016-03-25
    • 2011-10-14
    • 2011-09-15
    • 2015-02-25
    • 2012-05-27
    相关资源
    最近更新 更多