ページ 1 / 1
初期値を網羅するには
Posted: 2015年1月02日(金) 02:21
by mkai
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: 初期値を網羅するには
Posted: 2015年1月02日(金) 04:51
by かずま
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: 初期値を網羅するには
Posted: 2015年1月02日(金) 05:03
by かずま
かずま さんが書きました:mkai さんが書きました:
int が 32ビットの場合、32個までの数列に制限されます。
1 << 32 は、未定義の動作なのでダメですね。
それに int は符号があるので、unsigned にして、さらに
N は 31 までということにしておいてください。
Re: 初期値を網羅するには
Posted: 2015年1月02日(金) 06:04
by かずま
実際には、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;
}
Re: 初期値を網羅するには
Posted: 2015年1月02日(金) 15:58
by mkai
かずまさん
返信ありがとうございます。
かずま さんが書きました:
64通りですね。
間違えました、2^6=64ですね。
なるほど…やはり数列の数が大きくなると難しいですよね…
分かりました。ありがとうございます!