これは、配列内の反転をカウントするためのJavaコードです。'count'の値が異なる再帰間で保持されないのはなぜですか?
private void findInversions(int begin, int end, Integer count) {
System.out.println("begin: " + begin + ", end: " + end + ", and count is " + count);
if (end - begin < 1)
return;
int middle = (begin + end)/2;
findInversions(begin, middle, count);
System.out.println("begin: " + begin + ", end: " + end + ", here count is " + count);
findInversions(middle + 1, end, count);
mergeAndCount(begin, middle, end, count);
System.out.println("begin: " + begin + ", end: " + end + ", count now is: " + count);
}
private void mergeAndCount(int begin, int middle, int end, Integer count) {
int[] result = new int[end - begin + 1];
int aptr = begin;
int bptr = middle + 1;
for (int i = 0; i < result.length; i++) {
if (aptr <= middle && bptr <= end) {
if (numbers[aptr] < numbers[bptr]) {
result[i] = numbers[aptr];
aptr++;
}
else { // numbers[aptr] > numbers[bptr]
// (a[aptr], b[bptr]) is an inversion here
count++;
System.out.println("Found: (" + numbers[aptr] + "," + numbers[bptr] + ") " + count);
result[i] = numbers[bptr];
bptr++;
}
}
else if (aptr > middle) {
result[i] = numbers[bptr];
bptr++;
}
else if (bptr > end) {
result[i] = numbers[aptr];
aptr++;
}
}
for (int i = 0; i < result.length; i++) {
numbers[begin + i] = result[i];
}
}
反転がうまく印刷されているが、それは再帰呼び出しが戻った後にその価値を失うのでcount
は、決して正しいです。私は数回デバッグしましたが、再帰が終了したときにcount
が再び0になったことがわかりましたが、なぜそれを見つけることができませんでした。誰でも説明できますか?
なぜあなたはそれが保存されると思いますか? Javaは、 'Integer'オブジェクトなどの参照を含むすべての値渡しを使用します。 'count ++'は新しい 'Integer'オブジェクトを生成することに注意してください。すべてのJavaラッパー・タイプは不変です。もしあなたが望むのであれば、 'AtomicInteger'を可変ラッパー型として使うことができます。 –
は' 'javaがpass-by-value'であるためです(http://stackoverflow.com/questions/40480/is-java-pass-参照渡しによる値渡し) – SomeJavaGuy
Integerクラスはjavaで不変ではありませんか? –