2017-03-10 4 views
3

文字列をMATLABの数値と関連付けることを試みています。それは私が事がある文字列を数値に関連付ける検索可能なオブジェクトを作成する最速の方法

string: 'abcd', index: 1 
string: 'abdd', index: 2 
etc. 

を形をとり、オブジェクトを作成したい、ですが、私は、例えば、文字列で提供された場合、オブジェクトを検索できるように「ABCD」とそれを返すために取得する必要があります関連する(一意の)索引、この場合は1です。私はまた、インデックスを使用してオブジェクトを検索し、関連付けられた文字列を返すことができる必要があります。新しい要素をこのオブジェクトにかなり頻繁に追加する必要があります。このオブジェクトには多くの要素があります(500000のオーダー)。文字列そのものは一般的に「順序付けられていません」(もしそのようなものが助けても)。

質問: MATLABでこれを行う最も速い方法は何ですか?私が試した何


MATLABでのMapクラスは関連性があるように思え。しかし、私は両方向で検索する方法を理解することはできません。私はそれによって意味することはMathworks社のウェブサイト上で提供される次の例で説明します。

ticketMap = containers.Map(... 
{'2R175', 'B7398', 'A479GY', 'NZ1452'}, ... 
{'James Enright', 'Carl Haynes', 'Sarah Latham', ... 
'Bradley Reid'}); 
ticketMap('2R175') -> returns James Enright 

しかし、つまり、「ジェームズ・エンライト」は返却してもらう「与えられ、他の方向での検索がサポートされていないようです2R175 '。私もMap2コード(http://www.mathworks.com/matlabcentral/fileexchange/40323-map2-enhanced-map-class)を試しましたが、非常に遅いです。

+0

文字列をセル配列に配置し、セル配列のインデックスをインデックスとして使用することについて考えましたか?あなたは 'is member'を使って簡単にセル配列を検索できます。 – Cecilia

+2

A - > BとBB - > AAという2つのマップオブジェクトを作成しようとしましたか?AAはAAのコピーで、Bはキーマップペアの挿入/削除ごとにBBのコピーです。その場合、検索する必要のあるマップオブジェクトを示す文字列の属性が必要になることがあります。 – Abhinav

+0

大量のデータを持っているときにデータベースを使用しようとすると、テーブルからデータを追加、検索、削除することができるデータベースで、高速で信頼性が高く、実装が難しくありません。データベースを使うのが好きです) –

答えて

4

チケットから名前へのマップと名前からチケットへのマップの2つのマップを作成するのが最善の解決策であると考えます。

例:

tickets = {'2R175', 'B7398', 'A479GY', 'NZ1452'}; 
names = {'James Enright', 'Carl Haynes', 'Sarah Latham', 'Bradley Reid'}; 

ticketMap = containers.Map(tickets, names); 

namesMap = containers.Map(names, tickets); 
%ticketMap('2R175') -> returns James Enright 
%namesMap('James Enright') -> 2R175 

作成とメモリの無駄、と計算時間と思われるかもしれない二つのマップを管理しますが、time-time complexity、それが最も効率的なソリューションです。

1

文字配列と関連するインデックス配列のセル配列を保持するエラーチェックが制限されているオブジェクトが最速のソリューションだと思います。次に、単純なインデックスとstrcmpの組み合わせを使用して、または必要に応じてプルすることができます。

ここでは、そのようなオブジェクトの簡単な例を示します(私はそれらを好きで過去にはより良いパフォーマンスを見たので、字句クロージャを使用しています。

function store = makeStringMap(strings) 

    if (nargin >= 1) && not(isempty(strings)) 
     if iscellstr(strings) 
      strings = strings(:); 
     elseif ischar(strings) 
      strings = cellstr(strings); 
     else 
      error('makeStringStore:wrongInputType',... 
       'First input ''strings'' must be either a cellstr or a char array.'); 
     end 
    else 
     strings = {}; 
    end 

    nstrings = numel(strings); 
    indices = 1:nstrings; 

    store.append = @(string) append(string); 
    function [] = append(string) 
     if ischar(string) 
      string = cellstr(string); 
     end 
     nstring = numel(string)      ; 
     strings = [strings;string]      ; 
     indices = [indices,(1+nstrings)+(0:(nstring-1))] ; 
     nstrings = indices(end)       ; 
    end 

    store.getStringByIndex = @(index) getStringByIndex(index); 
    function string = getStringByIndex(index) 
     if all(index>0 && index<=nstrings) 
      string = strings(index); 
     end 
    end 

    store.getIndexByString = @(string) getIndexByString(string); 
    function index = getIndexByString(string) 
     if ischar(string) 
      string = cellstr(string); 
     end 
     nstring = numel(string); 
     index = zeros(nstring,1); 
     for k = 1:nstring 
      index = indices(strcmp(strings,string{k})); 
     end 
    end 

    store.getStrings = @() getStrings(); 
    function out = getStrings() 
     out = strings; 
    end 
end 

簡単なテストの実行:

>> s = makeStringMap(char(randi([97,122],5,10))); 
>> s.getStrings() 
ans = 
    'yheepozpvs' 
    'kkdrslqcic' 
    'smktndqhjg' 
    'nfqikjtsbb' 
    'jpfgtdlbem' 
>> s.getStringByIndex(2) 
ans = 
    'kkdrslqcic' 
>> s.getIndexByString(s.getStringByIndex(2)) 
ans = 
    2 
>> s.append(char(randi([97,122],3,10))); 
>> s.getStringByIndex(7) 
ans = 
    'tajrjqmikg' 
>> s.getIndexByString(s.getStringByIndex(7)) 
ans = 
    7 

私は変数stringたくさん使うんが、それは私がR2016aを実行すると、まだ使用していますので、新しいstringクラスではないことに注意しましょうcharおよびcellstrが多い。

関連する問題