3 回答
TA贡献1789条经验 获得超8个赞
如果答案要求您自己进行循环,那么这样的事情应该可以正常工作(执行此操作的几种方法之一,但是是O(n)):
public void addBefore(int x) {
if(length + 1 >= a.length){
int[] b = new int[a.length*2];
b[0] = x;
for (int i = 0; i < length; i++) {
b[i + 1] = a[i];
}
a = b;
} else {
for (int i = length; i >= 0 ; i--) {
a[i + 1] = a[i];
}
a[0] = x;
}
length++;
}
我注意到这开始运行“速度测试” - 不确定这样的测试有多有用,因为它将基于 cpu 性能,而不是测试算法的复杂性..
TA贡献1806条经验 获得超5个赞
无论您是先添加还是最后添加,只有在数组已满时才需要增加数组大小。
该count字段似乎与 完全相同length,并且index作为一个字段似乎未使用且无意义,因此将它们都删除。
要重新排列数组中的值,请使用以下方法:
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
你的两个“添加”方法应该是:
public class IntArrayList {
private int[] a; // Underlying array
private int length; // Number of added elements in a
// other code
public void add(int x) {
if (length == a.length) {
int[] b = new int[a.length * 2];
System.arraycopy(a, 0, b, 0, length);
a = b;
}
a[length++] = x;
}
public void addBefore(int x) {
if (length < a.length) {
System.arraycopy(a, 0, a, 1, length);
} else {
int[] b = new int[a.length * 2];
System.arraycopy(a, 0, b, 1, length);
a = b;
}
a[0] = x;
length++;
}
}
TA贡献1856条经验 获得超5个赞
您的解决方案存在三个问题:
您增加了
a
每次调用该方法的长度。这将很快创建一个OutOfMemoryException
当你从
a
to复制值时b
,你做了b[i+a.length] = a[i];
这意味着这些值将被复制到中间b
而不是只移动一个位置最后,您将新值放在数组的末尾而不是开头。
我之所以能看到这一切,是因为我在您的代码上使用了调试器。如果您希望能够检测和修复代码中的问题,则需要开始使用此工具。
所以固定的解决方案会这样做:
检查是否
a
已满(就像使用add()
方法完成一样),如果是,则创建b
并将所有内容复制到其中,依此类推)将所有值前移一位。最简单的方法是从长度向后循环到
0
在数组的开头分配新值
这是一个可行的解决方案:
public void addBefore(int x) {
// increase length if a is full
if (length >= a.length) {
int[] b = new int[a.length * 2];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
a = b;
}
// shift all values one cell ahead
for (int i = length; i > 0; i--) {
a[i] = a[i-1];
}
// add new value as first cell
a[0] = x;
length ++;
}
}
添加回答
举报