我正在使用来自median of median的Foundations of Algorithms算法选择第k个元素,而我在java中实现它时遇到了麻烦。我得到一个数组越界错误,并想知道是否有人可以帮我正确实现这个算法。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at test2.selection2(test2.java:23)
at test2.select4(test2.java:16)
at test2.partition2(test2.java:55)
at test2.selection2(test2.java:27)
at test2.select4(test2.java:16)
at test2.partition2(test2.java:55)
at test2.selection2(test2.java:27)
at test2.select4(test2.java:16)
at test2.main(test2.java:11)
这些是变量的值:
N size = 10
low = 0
high = 10
k = 3
arraysize = 10
r = 2
i = 1,2,3
first = 0,5,10
last = 4,9,11
lower = 7, 33
upper = 10, 44
-pivotitem
T size = 2
low = 0
high = 2
k = 1
arraysize = 10
r = 0
high==low [0]
list is empty
由于我的数组从大小10开始,r将是2.当从pivotitem再次调用partition2时,r将为0,从而产生大小为0的数组T.然后低和高将等于0,什么都不返回,是我收到错误的地方。我不知道为什么会发生这种情况,因为我的代码类似于书中的算法。
答案 0 :(得分:0)
您的交换方法看起来好像它将索引作为参数,但您使用值
来提供它list = swap (list[i], list[j], list);
这不是你的错误的根源,并且在更改调用后错误仍然存在,但也许你错了很多次。顺便说一句:代码在哪里?
答案 1 :(得分:0)
原来是C-Code?使用&调用partition2
index& pivotpoint)
表示调用者可以看到引用,即更改的结果。
你似乎用静态'thepivotpoint'来解决这个问题,但是你不能将它用作参数;它只会隐藏静态成员。
public static void partition2 (int[] list, int low, int high) // , int pivotpoint)
/* unchanged */
thepivotpoint = j - 1;
list = swap (mark, thepivotpoint, list);
}
仍然不完整。
答案 2 :(得分:0)
我还有其他一些改进,没有解决方案,但可能是更好的基础:
(int[], int, ...)
if ... return else ...
删除了其他内容。 show
的方法,它触发一个计数器,在无限循环中停止。删除了没有帮助我的评论。也许你可以添加更好的评论。
import java.util.Arrays;
public class Pivot
{
static int thepivotpoint;
public static void main(String[] args)
{
int[] list = {17, 10, 44, 7, 7, 33, 24, 10, 48, 49 };
thepivotpoint = 0;
System.out.println (select4 (list, list.length, 3));
}
public static int select4 (int[] list, int high, int k)
{
return selection2 (list, 0, high, k);
// return selection2 (list, 1, high, k);
}
public static int selection2 (int[] list, int low, int high, int k)
{
if (high == low)
return list[low];
partition2 (list, low, high);
if (k == thepivotpoint)
return list [thepivotpoint];
if (k < thepivotpoint)
return selection2 (list, low, thepivotpoint - 1, k);
return selection2 (list, thepivotpoint + 1, high, k);
}
static int count = 0;
public static void show (int [] T)
{
for (int i : T)
System.out.print (i + "\t");
System.out.println ();
if (++count > 20) System.exit (1);
}
public static void partition2 (int[] list, int low, int high)
{
int arraysize = high - low;
int r = (int) Math.ceil (arraysize / 5);
int [] T = new int[r+1];
for (int i = 1; i <= r; i++)
{
int first = low + 5 * i - 5;
int last = Math.min (low + 5 * i - 1, arraysize);
T [i] = median (list, first, last);
}
show (list);
approximateTheMedian (T, r, low, high, list);
}
public static void approximateTheMedian (int [] T, int r, int low, int high, int [] list)
{
int pivotitem = select4 (T, r, (r + 1) / 2);
int j = low;
int mark = 0;
for (int i = low; i < high; i++)
{
if (list[i] == pivotitem)
{
list = swap (i, j, list);
mark = j; //mark where pivotitem placed
j++;
}
else if (list[i] < pivotitem)
{
list = swap (i, j, list);
j++;
}
}
thepivotpoint = j - 1;
list = swap (mark, thepivotpoint, list);
}
public static int median (int[] list, int start, int end)
{
int [] copy = (int[]) list.clone ();
Arrays.sort (copy);
return copy [(start + end) / 2];
}
public static int[] swap (int one, int two, int[] list)
{
int dummy = list[one];
list[one] = list[two];
list[two] = dummy;
return list;
}
}