3

たとえば、論理値のみを含むベクトルがあるとします。

V = [1 0 1 0 1 1 1 1 0 0]

Sの「ストリーク」ベクトルを返す関数をMATLABで記述したいと思いますV。ここで、S(i)は、V(i)までのVの連続する1の数を表します。上記の例では、ストリークベクトルは次のようになります。

S = [0 1 0 1 0 1 2 3 4 0] 

非常に大きな行列に対してこれを実行する必要があることを考えると、ベクトル化/効率化されたソリューションをいただければ幸いです。

4

3 に答える 3

1

これでうまくいくはずです:

S = zeros(size(V));
for i=2:length(V)
    if(V(i-1)==1)
        S(i) = 1 + S(i-1);
    end
end

複雑さはO(n)だけで、これで十分だと思います。

サンプル入力の場合:

V = [1 0 1 0 1 1 1 1 0 0];
S = zeros(size(V));
for i=2:length(V)
    if(V(i-1)==1)
        S(i) = 1 + S(i-1);
    end
end
display(V);
display(S);

結果は次のようになります。

V =

     1     0     1     0     1     1     1     1     0     0


S =

     0     1     0     1     0     1     2     3     4     0
于 2013-03-26T03:51:13.127 に答える
1

また、いくつかの中間ステップで完全にベクトル化することもできます。

V = [1 0 1 0 1 1 1 1 0 0];

Sall = cumsum(V);
stopidx = find(diff(V)==-1)+1;
V2=V;
V2(stopidx) = -Sall(stopidx)+[0 Sall(stopidx(1:end-1))];
S2 = cumsum(V2);

S = [0 S2(1:end-1)];

しばらく時間がかかるのはAfaikだけですfind。絶対インデックスが必要なため、どこでも論理インデックスを使用してfind呼び出しをバイパスすることはできません。

于 2013-03-26T09:33:43.350 に答える
0

箱の外にありますが、テキスト関数の使用を検討しましたか?文字列はMatlabの単なるベクトルであるため、使いやすいはずです。

Regexpには、繰り返される値を見つけるための優れた関数がいくつか含まれています。

于 2013-03-26T08:23:21.050 に答える