如何反转数组的切片 java
How to reverse slice of array java
我一直在尝试反转 java 中列表的一部分。
python 中的等价物(虽然可能不是最好的方法——我不关心这个,只是想表达我的观点)是:
myList = [0,1,2,3,4,5,6,7,8,9,10]
reverseSlice = myList[2:6]
reverseSlice.reverse()
myList[2:6] = reverseSlice
当我尝试在 Java 中手动实现时,我试过这个:
public static int[] reverse(int[] x,int a1, int a2) {
a1--;
int[] rArr = new int[a2-a1+1];
for (int ind = a1; ind<a2; ind++) {
rArr[a2-ind-1] = x[ind];
}
for (int ind = a1; ind<a2; ind++) {
x[ind] = rArr[ind];
}
return x;
}
然而,当我运行这个:
int[] cows1 = new int[]{0,1,2,3,4,5,6,7,8,9,10};
cows1 = reverse(cows1,2,6);
for (int i : cows1) {
System.out.print(i + " ");
}
我得到 0 4 3 2 1 0 6 7 8 9 10
.
我真的很困惑我是怎么得到这个的,因为在我的函数中,我没有引入新值,所以“0”不应该出现。
我的问题:为什么我的代码返回的值不在列表中?
即将到来的 0 值可能是因为从 rArr 数组访问了一个未初始化的值。为了反转的目的,不需要额外的数组。您可以简单地将值从起始索引交换到结束索引。我测试了下面的代码,它给出了正确的输出
public class Solution2 {
public static void main(String args[])
{
int[] cows1 = new int[]{0,1,2,3,4,5,6,7,8,9,10};
cows1 = reverse(cows1,2,6);
// both indices are inclusive
for (int i : cows1) {
System.out.print(i + " ");
}
}
public static int[] reverse(int[] x,int a1, int a2) {
for (int i = 0; i < (a2-a1+1)/2; i++) {
swap(x,a1+i,a2-i);
}
return x;
}
private static void swap(int[] x, int i, int j) {
// System.out.println("values swappeed are "+ x[i] + " " + x[j]);
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
输出结果为
0 1 6 5 4 3 2 7 8 9 10
问题似乎出在您的 reverse
函数的第一行:a1--;
没有保留起始索引的原始值。
方法调用
reverse
函数的目的是仅反转数组中受变量值 a1
和 a2
约束的部分。附带一提,永远不要使用那样无意义的名称。这些变量的更好名称可能是 startIndex
和 endIndex
或类似的命名(a1
和 a2
没有任何意义)。
对于值 (2, 6),reverse
函数应该提取数组中从索引 2 开始到索引 6 结束的部分。我假设结束索引不包含在内,所以它应该仅获取索引 2、3、4 和 5 处的值。但是,该方法所做的第一件事是递减起始索引,因此它实际上从索引 1 开始。
从那里开始,该函数成功地反转了位于这些索引 [4,3,2,1] 的值。现在的问题是,索引 5 处的值会发生什么变化?让我们看看这部分代码做了什么new int[a2-a1+1]
。 a2
的值为 6 而 a1
的 new 的值为 1,因为它在第一行被递减了。这意味着您的新数组的大小为 [6-1+1],即 6。这似乎是不正确的。只需要反转 4 个值,数组的一个元素太大了。该数组的最后一个索引默认为 0
.
的整数值
交换
第一个循环:
for (int ind = a1; ind<a2; ind++) { // starts with a1 = 1 and a2 = 6
rArr[a2-ind-1] = x[ind]; // rArr[4] = x[1]: first iteration is off by 1
}
第二个循环:
for (int ind = a1; ind<a2; ind++) { // a1 = 1, a2 = 6 (starts at 1 and ends at 5 (rArr doesn't have an index 5)
x[ind] = rArr[ind]; // first iteration: x[1] = rArr[1], last iteration x[5] = rArr[5] -> this last index is accessible because array was too big and was initialized to a primitive `int` default value (0).
}
解决方案
- 确保保留开始和结束索引。
- 使用原始开始和结束索引为您的计算分配临时数组(如果需要)。
在 reverse()
方法中,您的第一行应该是:
int[] rArr = new int[a2-a1]; // allocates an array of size 4 (6-2)
从这里开始,如果方法的其余部分是错误的,您将不会在反转数组中的任何位置看到零。在最坏的情况下,如果您的起始索引计算错误,您会遇到偏移问题。而且,我认为,这很容易被发现和修复。
如果您是编程新手,即使您更像是一名“专家”,您也应该始终在纸上(或板上)解决这些问题,然后再尝试编写代码并遍历您的逻辑。您会惊讶于在编写代码之前会发现多少逻辑错误。
我一直在尝试反转 java 中列表的一部分。
python 中的等价物(虽然可能不是最好的方法——我不关心这个,只是想表达我的观点)是:
myList = [0,1,2,3,4,5,6,7,8,9,10]
reverseSlice = myList[2:6]
reverseSlice.reverse()
myList[2:6] = reverseSlice
当我尝试在 Java 中手动实现时,我试过这个:
public static int[] reverse(int[] x,int a1, int a2) {
a1--;
int[] rArr = new int[a2-a1+1];
for (int ind = a1; ind<a2; ind++) {
rArr[a2-ind-1] = x[ind];
}
for (int ind = a1; ind<a2; ind++) {
x[ind] = rArr[ind];
}
return x;
}
然而,当我运行这个:
int[] cows1 = new int[]{0,1,2,3,4,5,6,7,8,9,10};
cows1 = reverse(cows1,2,6);
for (int i : cows1) {
System.out.print(i + " ");
}
我得到 0 4 3 2 1 0 6 7 8 9 10
.
我真的很困惑我是怎么得到这个的,因为在我的函数中,我没有引入新值,所以“0”不应该出现。
我的问题:为什么我的代码返回的值不在列表中?
即将到来的 0 值可能是因为从 rArr 数组访问了一个未初始化的值。为了反转的目的,不需要额外的数组。您可以简单地将值从起始索引交换到结束索引。我测试了下面的代码,它给出了正确的输出
public class Solution2 {
public static void main(String args[])
{
int[] cows1 = new int[]{0,1,2,3,4,5,6,7,8,9,10};
cows1 = reverse(cows1,2,6);
// both indices are inclusive
for (int i : cows1) {
System.out.print(i + " ");
}
}
public static int[] reverse(int[] x,int a1, int a2) {
for (int i = 0; i < (a2-a1+1)/2; i++) {
swap(x,a1+i,a2-i);
}
return x;
}
private static void swap(int[] x, int i, int j) {
// System.out.println("values swappeed are "+ x[i] + " " + x[j]);
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
输出结果为
0 1 6 5 4 3 2 7 8 9 10
问题似乎出在您的 reverse
函数的第一行:a1--;
没有保留起始索引的原始值。
方法调用
reverse
函数的目的是仅反转数组中受变量值 a1
和 a2
约束的部分。附带一提,永远不要使用那样无意义的名称。这些变量的更好名称可能是 startIndex
和 endIndex
或类似的命名(a1
和 a2
没有任何意义)。
对于值 (2, 6),reverse
函数应该提取数组中从索引 2 开始到索引 6 结束的部分。我假设结束索引不包含在内,所以它应该仅获取索引 2、3、4 和 5 处的值。但是,该方法所做的第一件事是递减起始索引,因此它实际上从索引 1 开始。
从那里开始,该函数成功地反转了位于这些索引 [4,3,2,1] 的值。现在的问题是,索引 5 处的值会发生什么变化?让我们看看这部分代码做了什么new int[a2-a1+1]
。 a2
的值为 6 而 a1
的 new 的值为 1,因为它在第一行被递减了。这意味着您的新数组的大小为 [6-1+1],即 6。这似乎是不正确的。只需要反转 4 个值,数组的一个元素太大了。该数组的最后一个索引默认为 0
.
交换
第一个循环:
for (int ind = a1; ind<a2; ind++) { // starts with a1 = 1 and a2 = 6
rArr[a2-ind-1] = x[ind]; // rArr[4] = x[1]: first iteration is off by 1
}
第二个循环:
for (int ind = a1; ind<a2; ind++) { // a1 = 1, a2 = 6 (starts at 1 and ends at 5 (rArr doesn't have an index 5)
x[ind] = rArr[ind]; // first iteration: x[1] = rArr[1], last iteration x[5] = rArr[5] -> this last index is accessible because array was too big and was initialized to a primitive `int` default value (0).
}
解决方案
- 确保保留开始和结束索引。
- 使用原始开始和结束索引为您的计算分配临时数组(如果需要)。
在 reverse()
方法中,您的第一行应该是:
int[] rArr = new int[a2-a1]; // allocates an array of size 4 (6-2)
从这里开始,如果方法的其余部分是错误的,您将不会在反转数组中的任何位置看到零。在最坏的情况下,如果您的起始索引计算错误,您会遇到偏移问题。而且,我认为,这很容易被发现和修复。
如果您是编程新手,即使您更像是一名“专家”,您也应该始终在纸上(或板上)解决这些问题,然后再尝试编写代码并遍历您的逻辑。您会惊讶于在编写代码之前会发现多少逻辑错误。