0

以下のループをベクトル化することは可能ですか?

% String to parse (we want to create variables that are defined implicitly in the string):
parseStr = 'cubeId=001000_X=10_Y=10_Z=10_minX=8590_maxX=9200_minY=8590_maxY=9200_minZ=87_maxZ=95';

% Splitting string for regexp   
matchStr = '=|_';

[start_idx, end_idx, extents, matches, tokens, names, splits] = ...
   regexp(parseStr, matchStr);   

% Inspecting the splits
>> splits
splits = 
  Columns 1 through 8
    'cubeId'    '001000'    'X'    '10'    'Y'    '10'    'Z'    '10'
  Columns 9 through 15
    'minX'    '8590'    'maxX'    '9200'    'minY'    '8590'    'maxY'
  Columns 16 through 20
    '9200'    'minZ'    '87'    'maxZ'    '95'

% Loop that we are interested in vectorizing:
for ix = 1:2:numel(splits)
   fields.(splits{ix}) = splits{ix+1};
end

% Result:
>>fields
fields = 
    cubeId: '000900'
         X: '10'
         Y: '9'
         Z: '10'
      minX: '8590'
      maxX: '9200'
      minY: '7590'
      maxY: '8610'
      minZ: '87'
      maxZ: '95'
4

3 に答える 3

2

fieldsこれは正確にベクトル化されているわけではなく、既存の構造体を更新するのではなく、最初から作成することを意図している場合にのみ機能しますが、次のようになります。

fields = struct(splits{:});
于 2011-03-23T23:53:21.737 に答える
1

CELL2STRUCTを使用できます

cell2struct(splits(2:2:end),splits(1:2:end),2)
ans = 
    cubeId: '001000'
         X: '10'
         Y: '10'
         Z: '10'
      minX: '8590'
      maxX: '9200'
      minY: '8590'
      maxY: '9200'
      minZ: '87'
      maxZ: '95'

フィールドに数値を含める場合は、代わりに次のように記述できます。

cell2struct(cellfun(@str2double,splits(2:2:end),'uniformOutput',false),splits(1:2:end),2)

さらに、正規表現を変更して、すぐに構造体を返すようにすることができます(式全体を入力しませんでした。申し訳ありません)。

regexp(parseStr,'cubeId=(?<cubeId>\d+)_X=(?<X>\d+)','names')
ans = 
    cubeId: '001000'
         X: '10'
于 2011-03-23T23:52:42.370 に答える
0

Cellfun はコードをベクトル化しません。代わりに、引数を通過する内部ループがあります。

上記のコードは文字列のリストであるため、ベクトル化できません。ある時点で何を呼び出さなければならないかに関係なく、いくつかの for ループ。

実際、関数間で抽出呼び出しを行う必要があるため、cell2struct を呼び出す cellfun ソリューションは遅くなります。

私のマシンでは、for ループはせいぜい 0.0008 秒、cellfun ソリューションはせいぜい 0.0015 秒かかります。

于 2011-03-26T02:47:38.683 に答える