初期値を網羅するには

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mkai

初期値を網羅するには

#1

投稿記事 by mkai » 10年前

2進数の数列をある規則によって発展させる。
その時、初期値によって発展した結果が違うので初期値を網羅したいのですが
プログラムが少し冗長になってしまいます。
これを何とか短くしたいのですがどうすればよいでしょうか?
例えば
a[0]~a[5]の6個の数列の初期値は
000000~111111
の128通りありますが、今は

コード:

for(a[0]=0;a[0]<2;a[0]++){
for(a[1]=0;a[1]<2;a[1]++){
for(a[2]=0;a[2]<2;a[2]++){
for(a[3]=0;a[3]<2;a[3]++){
for(a[4]=0;a[4]<2;a[4]++){
for(a[5]=0;a[5]<2;a[5]++){
発展規則の式
}
}
}
}
}
}
のようにしているのですが、数が少ない数列であればまだいいのですが
数列の数を増やすと少し冗長になります。
これをコンパクトにまとめることはできないでしょうか?

分かりづらいかもしれませんがよろしくお願いします。

かずま

Re: 初期値を網羅するには

#2

投稿記事 by かずま » 10年前

mkai さんが書きました: a[0]~a[5]の6個の数列の初期値は
000000~111111
の128通りありますが、
64通りですね。
mkai さんが書きました: これをコンパクトにまとめることはできないでしょうか?

コード:

#include <stdio.h>

#define N  6

int main(void)
{
    int a[N], b, i;
    for (b = 0; b < 1 << N; b++) {
        for (i = 0; i < N; i++) {
            a[i] = b >> (N-1-i) & 1;
        }
        // 
        for (i = 0; i < N; i++)
            printf(" %d", a[i]);
        putchar('\n');
    }
    return 0;
}
int が 32ビットの場合、32個までの数列に制限されます。
int の代わりに long long を使うと、64個まで行けるかも
しれませんが、2の64乗 = 18446744073709551616 で、
こんな大きな個数の数列を全部試すのは無理でしょう。

かずま

Re: 初期値を網羅するには

#3

投稿記事 by かずま » 10年前

かずま さんが書きました:
mkai さんが書きました: int が 32ビットの場合、32個までの数列に制限されます。
1 << 32 は、未定義の動作なのでダメですね。
それに int は符号があるので、unsigned にして、さらに
N は 31 までということにしておいてください。

かずま

Re: 初期値を網羅するには

#4

投稿記事 by かずま » 10年前

実際には、N が 30 で10億通りを実行することすら
難しいでしょうから、最初のプログラムで十分です。

でも、例えば N が 20だとして、
a[17], a[18], a[19] などは頻繁に変化しますが、
a[0], a[1], a[2] などはほとんど変化しません。
それなのに、毎回 b から a[0]~a[19] を作り直すのは無駄ですね。

ということで、次のようなコードも考えられます。

コード:

#include <stdio.h>

#define N  6

int a[N];

void step(int i)
{
    int k;
    if (i < N)
        for (k = 0; k < 2; k++) {
            a[i] = k;
            step(i+1);
        }
    else {
        // a[0]~a[N-1] を使う。例えば
        for (k = 0; k < N; k++) printf(" %d", a[k]);
        putchar('\n');
    }
}

int main(void)
{
    step(0);
    return 0;
}

mkai

Re: 初期値を網羅するには

#5

投稿記事 by mkai » 10年前

かずまさん
返信ありがとうございます。
かずま さんが書きました: 64通りですね。
間違えました、2^6=64ですね。

なるほど…やはり数列の数が大きくなると難しいですよね…
分かりました。ありがとうございます!

閉鎖

“C言語何でも質問掲示板” へ戻る