Java学習 今更ながらインクリメント/デクリメントの前置後置の使い分けについて
2分探索方アルゴリズムを実装していたのですが、その際テキストに書いてあるようにやってもうまくいかない部分がありました。
結果的に私の方が間違っていたので、同じ間違いを2度と起こさないようにまとめておきます。
package check;
public class main {
public static void main(String[] args) {
int number = 10;
int samenumber = 10;
int before = ++number;
int after = samenumber++;
System.out.println(before);
System.out.println(after);
}
}
出力結果が「11」と「10」になるのは、おそらく99%の人がわかると思います。
for文やwhile文、if文の条件分岐の中でも何気なく書いていると思います。
これは「++number」でも「number++」でもその行を過ぎれば、結果的に同じ数字になっているからです。
私の今回の間違いは、条件判定に使う変数に「number++」のように後置インクリメントで代入してしまったことでした。
package binarySearch;
public class Main {
public static void main(String[] args) {
int[] array2 = { 1, 2, 3, 4, 5, 6 };
int head = 0;
int tail = array2.length - 1;
int check = 6;
while (head <= tail ) {
int center = (head + tail) / 2;
System.out.println(array2[center]);
System.out.println(check);
if (array2[center] == check) {
System.out.println(center + "番目の要素が" + check + "です");
break;
}
if (check < array2[center]) {
tail = center--;
System.out.println("iftailは今" + tail);
} else {
head = center++;
System.out.println("ifheadは今" + head);
}
System.out.println("centerは今" + center);
System.out.println("headは今" + head);
System.out.println("tailは今" + tail);
}
}
}
配列の変数名がarray2なのは色々と書いているうちにarray2になってしまっただけなので気にしないでください。
ちなみにこのコードを実行すると、checkの値が6以上で無限ループに入ります。
なぜなら最初に代入されるはずのcenter + 1の値がcenterのまま代入されているからです。
((head + tail) / 2の値が四捨五入して4を超えることがなくなり、永遠に要素番号4の値「5」で条件判定し続け、head <= tailの条件式もtrueであり続ける。)
なぜこのようなミスが起こったのか?
それは前述しましたが、通り過ぎればi++も++iも一緒という一種の思い込みにあったと思います。
このようなミスを無くすためには、
代入する「数値」を何かに使う場合は、前置と後置を意識する。
もしくは+=などの計算結果が直感と一致するわかりやすい記述を使う。
この2つが考えられました。
今回このバグ取りに時間をかなり取られましたが、改めてインクリメント/デクリメントの前置と後置を意識するきっかけになりました。
この記事が気に入ったらサポートをしてみませんか?