切换阵列两个部分的位置

时间:2018-05-28 13:52:17

标签: java arrays

我有一个整数数组,代表一副卡片,其中有52张卡片,数字范围从1-52代表卡片。我正在尝试编写一个方法,该方法将数组中的两个位置作为参数将数组分成三个块。块1是低于第一位置的所有值,块2是位于两个位置之间的所有值(包括位置1和2处的值),块3是位于第二位置之上的所有值。然后我想在阵列中切换块1和3的位置。

对于值为:

的数组

1,2,3,4,5,6,7,8,9,10,11,12

设置positionOne(1),positionTwo(9)将给出数组:

11,12,2,3,4,5,6,7,8,9,10,1

这是我迄今为止所拥有的,几乎可以运作,但我认为它有错误:

int

}

有更好的方法吗?

5 个答案:

答案 0 :(得分:3)

使用Arrays.copyOfRangeSystem.arraycopy

代替循环
// make a copy of the first section before overwriting it
int[] copy = Arrays.copyOfRange (inputArray, from, to);
// overwrite the first section with the second section
System.arraysCopy(inputArray, sourcePosition, inputArray, from, copy.length);
// copy the original content of the first section to the second section
System.arraysCopy(copy, 0, inputArray, sourcePosition, copy.length);

您必须根据您的要求更改指数。

答案 1 :(得分:1)

我会这样接近它。

为你的三个临时区块创建三个arraylists。

从0->开始迭代你的数组。 position 1.将值移动到第一个数组列表中。

迭代从位置1开始到第2位结束。将所有值移动到sec0nd数组列表中。

然后从位置2 + 1开始遍历数组直到结束。

合并三个数组列表。

答案 2 :(得分:1)

有一种方法可以做到这一点。如果你想自己编写代码而不是仅仅使用现有的Arrays.copyOfRange(也许你想在现有的地方而不是生成一个新的数组)。

int lengthOfDeck = cards.length;
int[] newCards = new int[lengthOfDeck];
for (int i = 1; i <= lengthOfDeck; i++) {
  if (i >=pos1 && i <=pos2) {
     newCards[i-1]=i;
  }
  else if (i < pos1) {
    newCards[i-1]= i + pos2;
  } 
  else {
   newCards[i-1] = i - pos2;
  }

}

答案 3 :(得分:1)

不使用额外内存的方法怎么样?!

主要的想法是,如果您想要将数组向右或向左移动offs位置,您可以使用2 full for loops来执行此操作。我举个例子:

  1. 初始数组{1,2,3,4,5};我们希望将它向右移动2个位置(即offs=2),并将结果{4,5,1,2,3}
  2. 第一个循环用于反转所有元素:{5,4,3,2,1}
  3. 反向第一个offs元素的
  4. 第二个循环{4,5,3,2,1}
  5. 第三次循环用于反转其他元素:{4,5,1,2,3}
  6. 这就是全部!要解决您的任务,您必须执行两次,但第二次必须减少数组的长度以不移动最后的元素。

    这是一个例子:

    public static void main(String... args) throws IOException {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
        replace(arr, 1, 9);
        // arr = [11, 12, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
    }
    
    public static void replace(int[] arr, int pos1, int pos2) {
        rotate(arr, arr.length, -pos1);
        rotate(arr, arr.length - pos1, -pos2);
    }
    
    // offs > 0 - to the right; offs < 0 - to the left
    private static void rotate(int[] arr, int length, int offs) {
        offs = offs >= length ? length % offs : offs;
        length = Math.min(arr.length, length);
    
        for (int i = 0, j = length - 1; i < j; i++, j--)
            swap(arr, i, j);
        for (int i = 0, j = offs > 0 ? offs - 1 : length + offs - 1; i < j; i++, j--)
            swap(arr, i, j);
        for (int i = offs > 0 ? offs : length + offs, j = length - 1; i < j; i++, j--)
            swap(arr, i, j);
    }
    
    private static void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
    

    根据表现。你有4个完整for loops,每个都有一个交换。所以性能 O(n),不使用额外的内存。

答案 4 :(得分:0)

感谢Eran的提示,这里有一个更适合您需求的方法:

public int[] splitArray(int[] i, int position1, int position2)  {

        position2++;

        int[] piece1 = Arrays.copyOfRange(i, 0, position1);
        int[] piece2 = Arrays.copyOfRange(i, position1, position2);
        int[] piece3 = Arrays.copyOfRange(i, position2, i.length);

        System.arraycopy(piece3, 0, i, 0, piece3.length);
        System.arraycopy(piece2, 0, i, piece3.length, piece2.length);
        System.arraycopy(piece1, 0, i, piece3.length+piece2.length, piece1.length);

        return i;

    }