我有一个名为tournamentTreeKSelection
的函数,它查找数组中的第 K 个最大元素。该函数接受三个参数,数组、再次相同的数组以及 K 的值。发送数组的两个副本的目的是这样在递归调用期间,我可以修改数组的一个副本并仍然保留原始数组 I在那次通话期间发送的。这是代码:
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 类中的某些内容是静态的,但不应该是静态的。
有什么见解吗?
最佳答案
我认为你应该这样调用你的函数:
System.out.println(TournamentTree.tournamentKSelection(arr.clone(), arr.clone(), 1));
我还推荐关于数组并将它们传递给函数的有趣线程:
关于java - java中的函数多次调用时输出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34112469/