• ベストアンサー

ループの条件設定について

こんにちは。 題名の通り、ループ条件について質問です。 例えば Rという1次元配列(要素数は4)があり、この配列Rの値が全て0になった場合、ループを抜け出すというようなプログラムを組みたいのです。 上記の例のような要素数が少ない場合はdo-while文で論理演算子を使ってひたすら条件を書けばいいのですが、実際計算させるのは要素数が500とかなので、現実的にはちょっと無理だなと、他の方法を考えているのですが、良い考えが思い浮かびません。。 どなたかアドバイスをお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.8

おそらく、質問者の方が採用しているのは、 do { ... ここでいろいろな処理 } while(r[0] != 0 || r[1] != 0 !! r[2] != 0 !! r[3] == 0); というものですね。 これだと、「500個で大変」となるのもわかります。 この場合(具体的には既に回答があるとおりですが) int isAllZero(int R[], int max) { int i; for(i = 0; i < max; ++) if (R[i] != 0) return 0; // non zero なものが あれば、0 を返す return 1; // 全部探してみて、non zero がなければ、すべて0なので、1を返す } という関数を準備して、 do { ... いろいろな処理 } while (! isAllZero(R, 500)); などとできます。 気持ちは、「全部がゼロ」でない間ループ。

ashikiti
質問者

お礼

お礼が遅くなってすみません; >これだと、「500個で大変」となるのもわかります。 そうです、ちょっと前までは要素数がすくない計算だったのでそれで良かったんですけど(^^; ソース参考にさせて頂きます。 >気持ちは、「全部がゼロ」でない間ループ。 なるほどなるほど。イメージがつかみやすいです。 ありがとうございました!

すると、全ての回答が全文表示されます。

その他の回答 (8)

  • nk2
  • ベストアンサー率23% (6/26)
回答No.9

STLを使用したバージョンです。 色々と柔軟に使えます。 //---------------------------------------------------------- #include <algorithm> #include <iostream> #include <vector> //---------------------------------------------------------- template<typename T> class is_not_zero { private:  bool result; public:  is_not_zero():result(false){}  void operator()(const T& _b)  {   result |= _b;  }  operator bool() const  {   return result;  } }; //---------------------------------------------------------- int main() {  using namespace std;  vector<int> iList;  const int SIZE = 500;  for(int i=0;i < SIZE;++i)   iList.push_back(0);  bool bValue = for_each(iList.begin(),iList.end(),is_not_zero<int>());  cout << bValue; } //----------------------------------------------------------

ashikiti
質問者

お礼

お礼が遅くなってすみません; includeにしらない単語がずらり(-ω-;) 前のソースも含めて、参考にしてしっかりと勉強したいと思います。 何度も回答して頂き感謝しています。 --------------------------------------------------------- それから、この場を借りてみなさんにお礼を言いたいと思います。 みなさんの発想は本当に驚きで、自分の頭の固さが情けないです。ここらでしっかりと勉強してみたいと思います! 当初は1,2個自分と違う発想の考えが出ればいいかなと思っていたのですが、たくさんの回答を頂きまして、とても感謝しています。 本当にありがとうございました。 また何かありましたら、よろしくお願いします。 点数は、自分にすっと入ってきた感があった回答に入れたいと思います。

すると、全ての回答が全文表示されます。
回答No.7

配列の型にもよるかもしれないんですが・・・こんな感じではいかがでしょう? #include <stdio.h> #include <string.h> #define BUF_SIZE 500 int main() { int ari[BUF_SIZE]; int cmp_ari[BUF_SIZE]; int i; for( i=0;i<BUF_SIZE;i++ ) { cmp_ari[i] = 0; } do { // 処理; } while ( memcmp( ari, cmp_ari, BUF_SIZE )!=0 ); return 0; } 予め終了すべき形を別配列に作り、memcmp()で比較しています。

ashikiti
質問者

お礼

お礼が遅くなってすみません; 型はdoubleなんです。 これはint限定なんですかね?string.hというのも初耳なので、ちょっと自分で調べてみたいと思います。 ありがとうございました!

すると、全ての回答が全文表示されます。
  • nk2
  • ベストアンサー率23% (6/26)
回答No.6

//すべて0ならfalseを返す bool isNotAllZero(const int* array,int size) {  while(--size && !array[size]);  return array[0] || size; } int main() {  const int SIZE = 500;  int A[SIZE];    while(isNotAllZero(A,SIZE));  return 0 } まぁ、やっていることは#1の方と変わらないんだけど。 ”trueは0以外”と定義されていることを利用して、 関数をもっと簡潔にした版です。

ashikiti
質問者

お礼

お礼が遅くなってすみません; 改良までして頂きありがとうございます。 こちらも自分のプログラムを考えながら参考にさせて頂きます。 ありがとうございました!

すると、全ての回答が全文表示されます。
  • yakou850
  • ベストアンサー率49% (25/51)
回答No.5

自分の考えでは以下のようなプログラムで動きませんでしょうか? int r[4],num=4; int i,temp=0; while(1){ for(i=0; i<num; i++){ if(r[i]==0){ temp=temp+1; } } if(temp==num){ break; } } ちょっと無理やりな感じですが、 要素数を使えれば こんなソースもできるかと思います。

ashikiti
質問者

お礼

お礼が遅くなってすみません; 自分の元のプログラムを考えながら参考にさせて頂きます! ありがとうございました。

すると、全ての回答が全文表示されます。
回答No.4

動作環境が通常のパソコンであれば、要素が500程度では深刻な負荷にはならないと思いますので、まずは単純に500ループさせて判定させてみるので組んでみると良いと思います。 要素が劇的に増加するのであれば、配列の内容を操作する関数を作って、 →変更によって内容が0になる場合 「0の個数」を+1 →変更によって内容が0以外になる場合 「0の個数」を-1 と随時計算しておくと、ループの脱出判定は「0の個数」と「要素数」が一致するかを判定する1行で済みます。

ashikiti
質問者

お礼

お礼が遅くなってすみません; 参考にさせて頂きます。ありがとうございました!

すると、全ての回答が全文表示されます。
  • smat7
  • ベストアンサー率46% (7/15)
回答No.3

要素の値がどのように変化するのかがわからないのですが、一度にひとつの値しか変化しないのであれば一般的なテクニックとしては、それ以前に他の要素が0となっていることがわかっている→最後の要素が0になったところで条件成立とみなす。 という形が自然です。別のプロセスですべての値が決定されてから判定しなければならないのであれば すべての値を加算し(必要なら絶対値とする)0を判定する でしょうか(これなら0でない値を検出した時点で判定を打ち切る方がよいですね)

ashikiti
質問者

お礼

回答ありがとうございます。 そうですね要素の値変化も重要でした; 今回は全ての要素の値が出てから判断するパターンです。 >すべての値を加算し(必要なら絶対値とする)0を判定する 言われてみて、「あ、それでいいのか」と気づくアホな自分。。とても参考になります>< ありがとうございました。

すると、全ての回答が全文表示されます。
回答No.2

配列で現在0である数のカウンタを用意します。 はじめ、0の配列の数をセットします。 ある配列が非0から0になったときカウントアップ、ある配列が0から非0になったときカウントダウン。 必要なとき(配列に0などの値をセットするときなど)カウト数をチェックして、指定の数になっていたら抜けます。 現在、酔っぱらい中なのでコードの記述をする気力がありません。m(_ _)m

ashikiti
質問者

お礼

回答ありがとうございます。 正直まだ文章を読んだだけなので何とも言えませんが、参考にさせて頂きます。 ありがとうございました。

すると、全ての回答が全文表示されます。
回答No.1

/* array[0..size-1] がすべて0なら非0を返す */ int is_all_zero(cosnt int* array, int size) {   while ( size-- ) {   if ( *array != 0 ) return 0;   ++array; } return 1; } を用意しておき、 if ( is_all_zero(R,500) ) { ループを抜ける。} …ではダメですか?

ashikiti
質問者

お礼

回答ありがとうございます。 まだ未熟なので、プログラムをパッと見ただけではわかりません。 これから自分のプログラムと照らし合わせてじっくり考えたいと思います! ありがとうございました。

すると、全ての回答が全文表示されます。

関連するQ&A