我正在开发一个项目,我 使用Comparable对一组Integer对象进行排序。
我的add方法接受一个类型为E的项。如果我的size变量(跟踪我的数组中的元素theData [])是= 0(它被初始化为),我只需将该项放在Data [0]中
如果不是,我使用item.compareTo将项目与数组中已有的每个项目进行比较。如果compareTo的结果是< 0表示数组中的数字,我将所有数字移到该数字后面,然后向右移动,并在其前面插入项目。
如果compareTo返回0,表示该项等于数组中的数字,我什么都不做,因为我不想在数组中重复。
如果循环中没有compareTo语句返回-1或0,我将该项放在数组[size]中,即数组的末尾,因为它必须大于所有其他数字。
然而,这不起作用。每次我创建一个新的Set并向其添加一些数字,然后尝试使用for循环打印出我的集合的内容,我不断收到java.lang.ArrayIndexOutOfBoundsException:此行的10个错误:
theData[j + 1] = theData[j];
我尝试从头开始,用不同的逻辑重写我的循环,每次我都不停地撞到这堵墙。我知道我必须使用我的reallocate方法错误地移动或者不能正确地增加数组的大小,但是我无法绕过它。
import java.util.*;
public class Set<E extends Comparable<E>> {
String s;
String name;
private static final int INITIAL_CAPACITY = 10;
private E[] theData;
private int size = 0;
private int capacity = INITIAL_CAPACITY;
@SuppressWarnings("unchecked")
public Set() {
theData = (E[]) new Comparable[capacity];
}
public Set(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void add(E item) {
if (size == capacity) {
reallocate();
}
if (size == 0) { // If size is 0, add item to theData[0]
theData[size] = item;
size++;
return;
}
else { // Else compare the item to every item in loop.
for (int i = 0; i < size; i++) {
int result = item.compareTo(theData[i]);
if (result < 0) {
for (int j = 0; j < size; j++) { //If item is less than a number, shift everything
theData[j + 1] = theData[j]; //after that index to the right, and add item
theData[j] = item;
}
}
if (result == 0) {
return;
}
else { //If item is not less than or equal to any
theData[size] = item; //numbers in the array, add it to the end
size++;
}
}
}
}
/*
* if (size>=1){ int result = item.compareTo(theData[size-1]); if(result<0){
* E temp = theData[size-1]; theData[size-1] = item; theData[size] = temp; }
* if(result>1){ return; } }
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
return theData[index];
}
public int size() {
return size;
}
private void reallocate() {
capacity = 2 * capacity;
theData = Arrays.copyOf(theData, capacity);
}
}
编辑:我用来测试它的驱动程序方法 -
public class Driver {
String one = "two";
public static void main(String[] args){
Set<Integer> one = new Set<Integer>();
one.add(63);
one.add(20);
one.add(127);
one.add(10);
one.add(26);
one.add(15);
for(int i = 0; i < one.size(); i++){
System.out.println(one.get(i));
}
}
}
答案 0 :(得分:2)
当j == size - 1
时,theData[j+1]
会将您带出阵列。
你想在结束前循环到一个。
for (int j = 0; j < size - 1; j++) { //If item is less than a number, shift everything
theData[j + 1] = theData[j]; //after that index to the right, and add item
theData[j] = item;
}
所以我也看了你为插入所获得的逻辑,并没有任何意义。为什么要延迟插入?如果你有房间,只需添加它!
接下来,双循环实际上是在实现bubble sort,但是它有一个致命的缺陷:你永远不会完成交换;你只是反复覆盖你的价值观。你也没有在正确的方向上进行比较;如果左边的值大于而不是右边的值,你想要交换,因为你是从数组的开头开始的。
所以,有了......这就是实现的形式......
public void add(E item) {
if (size == capacity) {
reallocate();
}
theData[size++] = item;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1; j++) {
if (theData[j].compareTo(theData[j + 1]) > 0) {
// perform the swap (you need an extra variable!
}
}
}
}
我将交换实施作为读者的练习。
答案 1 :(得分:1)
首先,在你的移位循环中,你将新项目插入每个位置,而不是移动然后插入[i],因为你将数据[j]复制到下一个位置,但始终将项目分配给数据[j],是对的吗? 其次,你从数组的开头开始,因为j从0开始.J应该从i开始。 第三个和主要的错误,你验证结果&lt; 0然后验证IF结果== 0,更改ELSE IF,以便即使结果&lt; else也不执行0
答案 2 :(得分:0)
向右移动元素可以从右到左完成,如:
for (int j = size; j > i; j--) { // If item is less than a
// number, shift
// everything
theData[j] = theData[j - 1]; // after that index to the
// right, and add item
}
size++;
theData[i] = item;
break;// after insert the number, we can just break the for loop
插入新号码后,打破for循环,否则size
变量将不正确
else { // If item is not less than or equal to any
theData[size] = item; // numbers in the array, add it to the end
size++;
break;
}