こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

処理について

プログラミングの処理についての質問です。

α個のフラグがあり、状態はONかOFFになります。
αを3とすると全パターンは以下のようになります。
フラグ1=ON フラグ2=OFF フラグ3=OFF
フラグ1=OFF フラグ2=ON フラグ3=OFF
フラグ1=OFF フラグ2=OFF フラグ3=ON
フラグ1=ON フラグ2=ON フラグ3=OFF
フラグ1=ON フラグ2=OFF フラグ3=ON
フラグ1=OFF フラグ2=ON フラグ3=ON
フラグ1=ON フラグ2=ON フラグ3=ON
(全てOFFは無し)

それぞれのパターンをクラスに詰め込んでファイルを作る作業をしたいのですが、
良いループ方法が浮かびません。
尚、クラスに詰め込む順番は、フラグONが少ない順にしたいです。
(ループ処理中、「フラグON ○/3」のように処理進度をダイアログで出すためです)

お手伝い頂けたら幸いです。

投稿日時 - 2009-12-25 22:52:53

QNo.5547416

7u7

困ってます

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

とりあえず, 「ON の数は無視して全てのパターンを出したい」というなら単純に 2重ループで十分です.
for (int i = 1; i < (1 << n); ++i) {
for (int j = 0; j < n; ++j) {
if (i & (1 << j)) {
i のビットj は 1
} else {
i のビットj は 0
}
}
}
という形で完全に列挙できます. 必要なら unsigned long にすれば (最低) 31ビットまでは保証されます.
一方「ON の数が少ないものから順に出力したい」というなら配列を使うのがおそらくベターです. つまり, まず「1個だけ ON のもの」を
(1, 0, ..., 0), ..., (n, 0, ..., 0)
と列挙します. 次に「2個 ON のもの」を
(2, 1, 0, ..., 0), ..., (n, 1, 0, ..., 0), (3, 2, 0, ..., 0), ..., (n, n-1, 0, ..., 0)
と列挙します. 以下, 順に ON となるビット数を増やしながら挙げていけば 2^n-1通り全てを挙げることができます. ちょっと難しいように見えるかもしれませんが, よく見るとわりと単純なことがわかるはずです. 「2進数のインクリメント」が手と頭と紙と鉛筆でできれば, この方法も追っていくうちに理解できるでしょう.

投稿日時 - 2009-12-26 00:39:37

ANo.5

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

その「クラスに埋め込む」「ファイルを作る」というのは、何を意図してるのでしょうか?
クラスメソッドの引数にフラグ1~aを与えるなり、メンバ「フラグ1~a」を設定するなりして、なんかの計算がしたいのか?
フラグ1~aを作りだすクラスなのか?
一つのオブジェクトで扱うのは,1パターンのフラグなのか、全パターンなのか?
aは、実行時に1度設定されるのか、実行中に何度も変わるのか?
aの範囲は?

---
a個の独立したTrue/Falseフラグがある時には、aビットの整数(2進数)の各ビットの1/0と各フラグに対応させることができます。

整数flgの下位から順番にフラグ1,2,...と対応させたら、その状態を調べるときは
フラグ1 = flgの最下位ビット flg & (1 << ( 1 - 1 ) ) ;
フラグ2 = flgの下位から2ビット目 flg & (1 << ( 2 - 1 ) ) ;
...
フラグa = flgの下位からaビット目 flg & (1 << ( a - 1 ) ) ;
となります。

全組合せは flg=1~ ((2 << a ) -1 )で求まります( オール0は無いのですから)

そのまま毎回ビット演算で求めるもよし、先に計算して結果を配列に入れておくもよし、それは、使い方しだいです。
あと、C/C++では 0→false, 0以外→trueとあつかいますが、気になるのなら、 ((flg & (1 << ( a - 1 ) )) != 0 )とすれば、false(0)とtrue(1)に変換できます。


処理の順番が 不問なら、forループなりでflgを順番に変えるのが楽です。
質問にあるような1の数で順番に、となると、1~ ((2 << a ) -1 )を1の数でソートする、くらいしか思いつきません。
進行状態の表示だけの問題なら、内部処理はflgの順番、表示は1~a、とちょっとインチキ(^^)する、という手もあります。
そもそも、1の数に対して均等に分布していないので、 100 * flg /((2 << a ) -1 ) パーセントで表示するほうがいいかもしれません。

投稿日時 - 2009-12-26 01:10:59

ANo.4

true・falseも、1・0に変わりないですよ。
flg = flg | (1 << 1);(flg1 = true)
flg = flg | (1 << 2);(flg2 = true)
flg = flg | (1 << 3);(flg3 = true)
で。

全部埋め込む事が可能なら
flg = flg | 0x1;
とか
flg = flg | 0x4;
で、
if(a==1)
{}
else if(a==2)
{}
else if(a==3)
{}
・・・
}
ですかね・・・
ifの部分は関数にすることも可ですが、どっちにしろ全種類各必要があるのならばと思いまして。

他にいい方法があるようなので他の方の方法は期待して今後の参考にしたいと思っています。

投稿日時 - 2009-12-26 00:00:53

ANo.3

や, 私なら逆に配列で書きますね>#1.
「ON か OFF か」を覚えておくんじゃなくって, 「どのフラグが ON であるか」を覚えておくんですが.
あるパターンから次のパターンを作るのは事実上「次の組合せを作る」ことと等価で, これはいろんなやりかたがあります.

投稿日時 - 2009-12-25 23:33:01

お礼

Tacosan様。ご返答ありがとうございます。

私も一度は配列案を考えました。
αが3なら3×7の配列を用意して
trueかfalseを全パターン埋め込んでいく。

けれどもαが不定ですと、
うまい処理をどうも作る事ができずに。。。

投稿日時 - 2009-12-25 23:37:24

ANo.2

すみません。書き損じです。
1、それぞれのflgの数重視なら
for(i=0;i<3;i++)
if (flg & 0x01)
{
 cnt ++;
}
flg = flg >> 1;
}
}
です。

投稿日時 - 2009-12-25 23:17:11

お礼

ご返答ありがとうございます。

ただ申し訳ないのですが、
私の質問内容が不完全でtaunamlz様に勘違いをさせてしまいました。

まず、フラグの内容は「true」か「false」です。

そしてクラスにフラグの状態を詰め込む際、「ONの数」が最重要ではなく(重要な事には変わりませんが)
全てのフラグパターンの状態をクラスに詰め込まなければならないです。
【フラグ1=ON フラグ2=OFF フラグ3=OFF】と
【フラグ1=OFF フラグ2=ON フラグ3=OFF】では
結果的にはONフラグが1本ですが、
フラグ1のみONは前者のみ、フラグ2のみONは後者のみ、と
完全に別物です。

αも例文では3としていますが、
1の場合もありますし、9の場合もあります。

この事を考慮して頂けたら幸いです。

投稿日時 - 2009-12-25 23:33:24

ANo.1

どのようなフラグをお考えでしょうか?
int flg[3];
ですか?
だとしたら大変ですね。
俺なら
int flg;
です。
フラグの立て方は
flg = flg | 0x1;
とか
flg = flg | 0x4;
です。
そうするとループとしては
1、それぞれのflgの数重視なら
for(i=0;i<3;i++)
if (flg & 0x01)
{
 cnt ++;
}
}
で、フラグの数によってイベントを発生
2.フラグの値が重要だとしたら
ifでもcaseでも好きな方で
if(flg ==1)
{
イベント1
}
else if(flg ==2)
{
イベント2
}
しかないと思います。

参考になれば。

投稿日時 - 2009-12-25 23:16:01

あなたにオススメの質問