【问题标题】:Java: Shift/Rotate Object ArrayJava:移位/旋转对象数组
【发布时间】:2013-09-14 15:37:07
【问题描述】:

我的问题实际上应该很简单: 我有一个 Players 对象数组。(players[]) 我想要一个函数来旋转这个数组直到一个索引:

public void rotateArray(Object[] array, int index)

这将转换

{Player1, Player2, Player3, Player4, Player5}

索引为 2 到:

{Player3, Player4, Player5, Player1, Player2}

但我想防止引用出现问题。 我已经尝试过 System.arraycopy() 但要么我笨到让它工作,要么我是错误的方法。

【问题讨论】:

  • 你想对旋转后的数组做什么?
  • 我想用这个函数来设置调用这些对象的顺序。
  • 你不能按那个顺序迭代吗?每次执行数组复制都是一项昂贵的操作。
  • 迭代是什么意思?

标签: java arrays sorting reference rotation


【解决方案1】:

这种单线解决方案在原地旋转阵列,具有恒定的额外内存和线性时间:

Collections.rotate(Arrays.asList(array), -index);

【讨论】:

  • 我对此表示赞同。这怎么可能不是公认的答案?
【解决方案2】:

一个更有效的大数组解决方案,使用 O(1) 空间:

 public static void rotateArray(int[] a, int i) {
    i %= a.length;
    reverse(a, 0, a.length);
    reverse(a, 0, i);
    reverse(a, i, a.length);
 }

 public static void reverse(int[] a, int l, int r) {
    for (int left = l, right = r - 1; left < right; left++, right--) {
        int temp = a[left];
        a[left]  = a[right];
        a[right] = temp;
    }
  }

【讨论】:

  • 我不认为这个算法在所有情况下都是正确的。考虑序列 BCDA,其中目标是旋转直到 A 是第一个。在每个反转步骤,该算法都会产生:BCDA->ADCB->CDAB(不正确)。
  • 我已经检查并且代码工作正常。旋转循环向右发生。例如a= {1,2,3,4} i = 0 --> 没有旋转。 i = 1 --> a = {4,1,2,3} 等 i = 4 --> 将数组置于初始状态(i=a.length)。 i = 5 与 i = 1 相同,i = 6 与 i = 2 相同,以此类推
  • 我的错-我将“i”解释为旋转完成后应该首先出现的元素的索引,而不是要执行的旋转次数(因此设置 i = a.length- 1;)
  • 没问题。是的,i 不是索引,而是所有元素的一个位置向右移动
【解决方案3】:

必须复制数组才能使用arraycopy,我建议这样做,因为它应该是最快的。避免复制的唯一原因是数组非常大且内存紧张。

public void rotateArray(Object[] array, int index)
{
    Object[] result;

    result = new Object[array.length];

    System.arraycopy(array, index, result, 0, array.length - index);
    System.arraycopy(array, 0, result, array.length - index, index);

    System.arraycopy(result, 0, array, 0, array.length);
}

【讨论】:

  • 我会检查这个以确保没有错误或索引错误。
  • 注:对于任何试图将其用于广义旋转(负数或旋转大于数组长度)的人:此代码将崩溃。在开头插入:index %= array.length; if (index &gt; 0) { index += array.length; } 注意负数检查是必须的,因为Java的mod不是真正的数学mod:它可以产生负数。
  • 我以前从未听说过 System.arrayCopy...我以后会用这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 2019-08-16
相关资源
最近更新 更多