多次调用时,java中的函数输出不同的结果

时间:2015-12-06 00:11:01

标签: java

我有一个名为tournamentTreeKSelection的函数,它找到数组中第K个最大的元素。该函数有三个参数,数组,同一个数组和K的值。发送数组的两个副本的目的是在递归调用期间,我可以修改数组的一个副本并仍保留原始数组在电话会议期间发送。这是代码:

import java.util.ArrayList;
import java.util.Arrays;

public class TournamentTree {

public static int max(int a, int b) {
    return a > b ? a : b;
}

public static int[] toArray(ArrayList<Integer> list) {
    int[] arr = new int[list.size()];
    for(int i = 0; i < arr.length; ++i)
        arr[i] = list.get(i);

    return arr;
}

public static ArrayList<Integer> toList(int[] arr) {
    ArrayList<Integer> list = new ArrayList<>();
    for(int i : arr)
        list.add(i);

    return list;
}


public static int tournamentKSelection(int[] data, int[] data_copy, int k) {
    ArrayList<Integer> winners = new ArrayList<>();

    for(int i = 0; i < data.length; i += 2) {
        winners.add(max(data[i], data[i + 1]));
    }

    if(k > 1 && winners.size() == 1) {
        for(int i = 0; i < data_copy.length; i++)
            if(data_copy[i] == winners.get(0))
                data_copy[i] = -1;

        return tournamentKSelection(data_copy, data_copy, --k);
    }

    if(winners.size() % 2 == 1 && winners.size() != 1) winners.add(-1);

    if(winners.size() == 1) return winners.get(0);

    return tournamentKSelection(toArray(winners), data_copy, k);

}
}

现在我要测试一下:

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
       int[] arr = {9, 10, 8, 7, 6, 500, 4, 3, 2, 1};


       System.out.println(TournamentTree.tournamentKSelection(arr,arr,1));
       System.out.println(TournamentTree.tournamentKSelection(arr,arr,2));
       System.out.println(TournamentTree.tournamentKSelection(arr,arr,3));


}
}

这会产生以下结果:

500 // ok this is the first largest number
 10 // ok this is the second largest number
  8 // this is the fourth largest number, not the third

现在让我单独调用System.out.println(TournamentTree.tournamentKSelection(arr,arr,3));而不调用k = 1和k = 2

import java.util.Arrays;

public class Test {
public static void main(String[] args) {
int[] arr = {9, 10, 8, 7, 6, 500, 4, 3, 2, 1};


System.out.println(TournamentTree.tournamentKSelection(arr,arr,3));


}
}

现在这会产生正确的结果,即9.正在发生什么?单独地,结果是正确的但是当我先前调用相同的函数时,后续结果是错误的。

我现在能想到的唯一解释是我的TournamentTree类中的某些内容是静态的,不应该是。

有什么见解?

2 个答案:

答案 0 :(得分:2)

我认为你应该以这种方式调用你的函数:

System.out.println(TournamentTree.tournamentKSelection(arr.clone(), arr.clone(), 1));

我还推荐有关数组的有趣线程并将它们传递给函数:

Are arrays passed by value or passed by reference in Java?

答案 1 :(得分:1)

在调用TournamentTree.tournamentKSelection(arr,arr,3)中,您为两个args传递相同的数组,因此即使您没有通过第二个参数更改数组,您也会通过第一个参数更改它。 Java使用传递引用,而不是按值传递。要保留原文,您必须制作副本并传入其中,例如:

public static void main(String[] args) {
    int[] arr = {9, 10, 8, 7, 6, 500, 4, 3, 2, 1};
    int[] arr_copy = java.util.Arrays.copyOf(arr, arr.length);

    System.out.println(TournamentTree.tournamentKSelection(arr,arr_copy,3));
}