Search on the blog

2011年4月19日火曜日

memset()の有効活用

前にも書いたが、memset()は初期化時に重宝する。

今日、ある問題を解いていたときに、3次元配列の初期化に遭遇した。
しかも、0ではなく、INF(比較的大きな数字)に初期化したい。

どうしたものか。。

 まず、やったのが、fill()。
int main() {
int x[10][10][10];

fill(x, x+10, INF);
cout << x[0][0][0] << endl;
}
ダメだった。なぜ。。3次元だけど、メモリは縦に連続して展開されるんじゃないの??
同様にfill_n()も撃沈。
int main() {
int x[10][10][10];

fill_n(x, 10*10*10, INF);
cout << x[0][0][0] << endl;
}
ま、マジか。。。

 仕方ないので、愚直にループを書く。
int main() {
int x[10][10][10];

REP(i, 10) REP(j, 10) REP(k, 10) x[i][j][k] = INF;
cout << x[0][0][0] << endl;
}
んー、ちょっとダサいなー。
ちょっと考えてmemset()で行けるのではと気付く。

memset()は2進数・byte単位で初期化するので、大きな数にセットしようとして、
int main() {
int x[10][10][10];

memset(x, 0xFF, sizeof(x));
cout << x[0][0][0] << endl;
}
とするのはNG。これでは、すべての要素が-1にセットされます。(2の補数ですね。)

大きい数なら、0x7Fがいいでしょう。
しかし、INF + INF < INT_MAX(アルゴリズムコンテストの問題を解いていると、こういう条件を満たしたいことがしばしばありますよね!)を満たす範囲でなるべく大きいINFにセットしたい場合は、
0x3Fが妥当でしょう。
int main() {
int x[10][10][10];

memset(x, 0x3F, sizeof(x));
cout << x[0][0][0] << endl;
}
ちなみに、上記の値は、十進数で”1061109567”です。

0 件のコメント:

コメントを投稿