4

私はmatlabに次の文字列を持っています

V= 'abcdefghijklmnñopqrstuvwxyz';

次に、「V」アルファベットの文字で構成される 9 文字の単語があります。

k = 'peligroso';

アルファベットに従って単語「k」のインデックスを使用して正方行列 (3x3) を作成したい場合、これが出力になります。(私が検討している範囲は 0 から 26 であるため、'a' char のインデックスは 0 であることに注意してください)

   16 4 11
   8 6 18
   15 19 15

これを行うための私のコードは次のとおりです。

K = [findstr(V, k(1))-1 findstr(V, k(2))-1 findstr(V, k(3))-1;findstr(V, k(4))-1 findstr(V, k(5))-1 findstr(V, k(6))-1; findstr(V, k(7))-1 findstr(V, k(8))-1 findstr(V, k(9))-1];

しかし、同じことを達成するためのよりエレガントなソリューションが必要だと思います。何かアイデアはありますか?

PS: 文字 'ñ' はアルファベット内にある必要があるため、ASCII 値は使用していません。

4

3 に答える 3

7

ループのない解決策として、数値だけでなく文字列でも機能するISMEMBERを使用できます。

K = zeros(3); %# create 3x3 array of zeros

[~,K(:)] = ismember(k,V); %# fill in indices

K = K'-1; %# make K conform to expected output
于 2012-08-21T07:48:00.490 に答える
2

文字列は単なる文字の配列であるため、通常の配列処理関数を使用して文字列を簡単に操作できます。

たとえば、arrayfunを使用して、指定された関数を適用することで新しい配列を作成できます。これにより、同じサイズの出力配列が生成されます。reshapeを使用して、目的の3x3形状を形成できます。MATLABのreshapeは配列を列優先の順序で処理するため、最後に転置することに注意してください。

K = reshape(arrayfun(@(x) findstr(V, x)-1, k), 3,3)'

または、MATLABでは、行列のエントリを列の主要な順序で読み取る単一のインデックスを使用して行列にインデックスを付けることができるため、空の行列を作成し、そのエントリを1つずつ作成できます。

K = zeros(3,3)
for i=1:9
    K(i) = findstr(V, k(i))-1;
end
K = K'
于 2012-08-21T04:30:05.830 に答える
2

@Jonas のソリューション ( ismember) が好きです。これが最もエレガントな方法だと思います。ただし、別の解決策を提供するためだけに:

V = 'abcdefghijklmnñopqrstuvwxyz';
k = 'peligroso';

K = reshape( bsxfun(@eq, (k-0).', V-0) * (1:numel(V)).', 3,3).'

(SOの強調表示を許してください)

これの利点は、これが組み込み関数のみを使用することです(ismember少なくとも、私のMatlab R2010bでは組み込みではありません)。これは、このソリューションが よりも高速である可能性があることを意味しますがismember

  1. それが実際に正しいかどうかをテストする必要があります。

  2. 読みやすさを失うことを正当化するのに十分な大きさの複雑なケースを用意する必要がありますismember

Matlab のインデックスは 1 ベースであることに注意してくださいV(1) = a。上記のソリューションは 1 ベースの回答を生成しますが、0 ベースの例を提供します。10 ベースのインデックスが本当に必要な場合は、上記の行から差し引くだけです。

于 2012-08-21T09:34:26.310 に答える