1

MATLAB ドキュメンテーションでは、breakキーワードについて次のように説明しています。

  • breakfor または while ループの実行を終了します。break ステートメントの後のループ内のステートメントは実行されません。
  • ネストされたループでは、break はそれが発生したループからのみ終了します。制御は、そのループの終わりに続くステートメントに渡されます。

(私の強調)

複数のネストされたループから抜け出したい場合はどうすればよいでしょうか? Java などの他の言語には、制御の流れを転送する場所を指定できるラベル付きの breakがありますが、MATLAB にはそのようなメカニズムがありません。

次の例を検討してください。

% assume A to be a 2D array

% nested 'for' loops
for j = 1 : n
  for i = 1 : m
    if f(A(i, j)) % where f is a predicate
      break; % if want to break from both loops, not just the inner one
    else
      % do something interesting with A
    end
  end
  % <--- the break transfers control to here...
end
% <--- ... but I want to transfer control to here

両方のループを終了する (MATLAB での) 慣用的な方法は何ですか?

4

3 に答える 3

2

元の 特定の例では、線形インデックスと単一のループを使用するのではなく、次のように言います。

%// sample-data generation
m = 4;
n = 5;
A = rand(m, n);
temp = 0;

for k = 1:numel(A)
    if A(k) > 0.8 %// note that if you had switched your inner and outer loops you would have had to transpose A first as Matlab uses column-major indexing
      break; 
    else
      temp = temp + A(k);
    end
end

または、実質的に同じ (ただし、分岐が少ない):

for k = 1:numel(A)
    if A(k) <= 0.8 %// note that if you had switched your inner and outer loops you would have had to transpose A first as Matlab uses column-major indexing
      temp = temp + A(k);
    end
end

この答えはケースごとに異なり、慣用的に正しい解決策に適合する一般的なワンサイズはないと思いますが、問題に応じて次の方法でアプローチします(これらはすべて、ベクトル化された解決策が実用的ではないことを前提としていることに注意してください。それは明らかな最初の選択です)

  1. 入れ子の次元を減らし、breaks を使用しないか、1 つだけを使用しますbreak(つまり、上記のように)。
  2. 述語の計算に負荷がかかり、ループの反復回数が非常に多い場合を除き、 break はまったく使用しないでください。最後の余分な反復は実質的に無料です。
  3. 各レベルでフラグとブレークを設定することに失敗しました。
  4. または、最後にループを関数にラップし、return代わりに呼び出しますbreak
于 2015-10-08T07:02:47.813 に答える
1

私が知る限り、そのような機能は組み込まれていません。ただし、ほとんどの場合、matlab はベクトル化をサポートしているため、ネストされたループは必要ありません。ベクトル化が機能しない場合、ループはたいてい長くて複雑であるため、複数の改行があっても可読性が著しく損なわれることはありません。コメントに記載されているように、ここではネストされたループは必要ありません。ベクトル化はトリックを行いますが、

m = 5;
n=4;
x = rand(m,n);
tmp = find(x>0.8, 1, 'first');
if (isempty(tmp))
   tmp = m*n+1;
end
tmp = tmp-1;
tot = sum(x(1:tmp));

もちろん、for ループが必ずしも遅くはないと主張する人がいるかもしれませんが、Matlab は列が多く、複数のループを使用すると、ほとんどの場合、最適でない次元でのループが含まれるという事実が残ります。ベクトル化されたソリューションでは、そのようなループを回避するスマートな方法を使用できるため、その必要はありません (もちろん、入力が行ベクトルの場合は当てはまらないため、これを回避することも良いことです)。

于 2015-10-08T07:13:30.007 に答える