如何在MATLAB中使用哈希表(字典)



我需要通过字符串索引访问数据,如表('one')%返回1。MATLAB中有这样的数据结构吗?它是如何实现的?

在最新版本的MATLAB中,有containers.Map数据结构。有关详细信息,请参阅MATLAB Map容器。这消除了使用结构时的一些限制。例如

c = containers.Map
c('foo') = 1
c(' not a var name ') = 2
keys(c)
values(c)

一个结构可以用作一种哈希表:

>> foo.('one')=1
foo = 
    one: 1
>> foo.('two')=2;
>> x = 'two';
>> foo.(x)
ans =
     2

要查询结构是否包含特定字段(键),请使用isfield:

>> isfield(foo,'two')
ans =
     1

该方案的缺点是,只有同时也是有效的Matlab变量名的字符串才能用作键。例如:

>> foo.('_bar')=99;
??? Invalid field name: '_bar'.

要绕过这一限制,请使用Oli链接的问题中的一个解决方案。

只是添加到以前的答案中(无法对其他好的答案发表评论):一个结构查找,如下所示:

s={};
s.abc = 1;   %insert a value in the struct, abc is your lookup hash
out = s.abc; % read it back

使用结构实际读取值的速度大约是使用容器的10倍。如果感兴趣的,完整的测试代码如下

function s=test_struct_lookup_hash_speed
%% test how a struct lookup speed works vs container, interesting
    s = {};  % hash table
    v = {};  % reverselookup table for testing
    nHashes = 1E4;  % vary this to see if read speed varies by size (NOT REALLY)
    nReads  = 1E6;
    fprintf('Generating hash struct of %i entriesn', nHashes);
    tic
    for i = 1:nHashes
        hashStr = md5fieldname(randi(1E8));
        s.(hashStr) = i;
        v{end+1} = hashStr;  %reverselookup
    end
    toc
    fprintf('Actual HashTable length (due to non unique hashes?): %i, and length of reverse table: %in',length(fieldnames(s)), length(v) );
    fprintf('Reading %i times from a random selection from the %i hashesn', nReads, nHashes);
    vSubset = [ v(randi(nHashes,1,3))  ];
    for i = 1:length(vSubset)
       hashStr = vSubset{i};
       % measure read speed only
       tic
       for j = 1:nReads
         val = s.(hashStr);
       end
       toc
    end

    %% test CONTAINERS
    fprintf('Testing Containersn');
    c = containers.Map;
    fprintf('Generating hash struct of %i entriesn', nHashes);
    tic
    for i = 1:nHashes
        hashStr = md5fieldname(randi(1E8));
        c(hashStr) = i;
        v{end+1} = hashStr;  %reverselookup
    end
    toc
   fprintf('Reading %i times from a random selection from the %i hashesn', nReads, nHashes);
   vSubset = [ v(randi(nHashes,1,3))  ];
    for i = 1:length(vSubset)
       hashStr = vSubset{i};
       % measure read speed only
       tic
       for j = 1:nReads
         val = c(hashStr);
       end
       toc
    end    

    %% Get a valid fieldname (has to start with letter)   
    function h=md5fieldname(inp)
    h = ['m' hash(inp,'md5')];
    end

end

最新更新