代码之家  ›  专栏  ›  技术社区  ›  nmichaels

二郎双向哈希表

  •  6
  • nmichaels  · 技术社区  · 14 年前

    我正试图想出一个类似字典的数据结构,我可以在二郎使用。目标是确保所有的价值观以及关键点都是独一无二的。每次修改之后,我都可以通过显式的一致性检查来完成这项工作,但我希望有一个模糊的类型可以为我完成这项工作。有吗?如果没有,是否有比将检查包装到修改数据的每个函数中(或返回稍微不同的副本)更好的方法?

    我希望至少有120个元素,不超过几千个,以防这很重要。

    3 回复  |  直到 14 年前
        1
  •  6
  •   hdima    14 年前

    像这样的情况怎么样:

    -module(unidict).
    
    -export([
        new/0,
        find/2,
        store/3
        ]).
    
    
    new() ->
        dict:new().
    
    
    find(Key, Dict) ->
        dict:find({key, Key}, Dict).
    
    
    store(K, V, Dict) ->
        Key = {key, K},
        case dict:is_key(Key, Dict) of
            true ->
                erlang:error(badarg);
            false ->
                Value = {value, V},
                case dict:is_key(Value, Dict) of
                    true ->
                        erlang:error(badarg);
                    false ->
                        dict:store(Value, K, dict:store(Key, V, Dict))
                end
        end.
    

    Shell会话示例:

    1> c(unidict).
    {ok,unidict}
    2> D = unidict:new().
    {dict,0,16,16,8,80,48,
          {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
          {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}
    3> D1 = unidict:store(key, value, D).
    {dict,2,16,16,8,80,48,
          {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
          {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],
            [[{key,key}|value],[{value,...}|{...}]],
            []}}}
    4> D2 = unidict:store(key, value, D1).
    ** exception error: bad argument
         in function  unidict:store/3
    5> D2 = unidict:store(key2, value, D1).
    ** exception error: bad argument
         in function  unidict:store/3
    6> D2 = unidict:store(key, value2, D1).
    ** exception error: bad argument
         in function  unidict:store/3
    7> D2 = unidict:store(key2, value2, D1).
    {dict,4,16,16,8,80,48,
          {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
          {{[],
            [[{key,key2}|value2]],
            [],[],[],[],[],[],[],[],[],[],[],
            [[{value,value2}|{key,key2}]],
            [[{key,key}|value],[{value,...}|{...}]],
            []}}}
    8> unidict:find(key, D2).
    {ok,value}
    9> unidict:find(key2, D2).
    {ok,value2}
    
        2
  •  1
  •   Alexey Romanov    14 年前

    有吗?

    我相信不是在标准图书馆。我会用一对 dict() 和A set() 价值观。

        3
  •  1
  •   Zed    14 年前

    您可以对几百个元素使用简单的键、值列表:

    put(L, K, V) ->
      case lists:keyfind(K, 1, L) of
        {K, _} -> erlang:error(badarg);
        false ->
          case lists:keyfind(V, 2, L) of
            {_, V} -> erlang:error(badarg);
            false ->  [{K,V} | L]
          end
      end.
    
    get(L, K) ->
      case lists:keyfind(K, 1, L) of
        {K, V} -> {'value', V};
        false ->  'undefined'
      end.