仅使用一个分号在 Java 中旋转一个 int 数组

Rotating an int Array in Java using only one semicolon

我正在为 Java 做大量的自愿任务,其中包括使用基本数组和方法。我一直做得很好,直到我遇到了严重的障碍。

最初的任务是创建一个方法 rotateByN,它应该采用一个 int 数组并将其旋转 N 步(并影响输入数组,而不是 return 一个新数组)。足够简单:

public class Four {
    static void rotateByN(int[] in, int n) {
        for (int l = 1; l <= n; l++) {
            int tmp = in[0];
            for (int i = 1; i < in.length; i++) {
                in[i - 1] = in[i];
            }
            in[in.length - 1] = tmp;
        }
    }

    public static void main(String[] args) {
        int[] arr = { 2, 7, 6, 1, 0 };
        rotateByN(arr, 3);
        for (int r : arr) {
            System.out.println(r);
        }
    }
}

然而,后续任务是将方法体中使用的分号数量减少到一个。我花了大约一个小时浏览了各种可能性的文档,但似乎什么都没有。

更令人沮丧的是,如果我们可以只调用之前创建的函数 rotate(它做同样的事情,但总是恰好一次) N 次,但话又说回来,一个for 循环需要更多我们没有的分号。

我不想这么直截了当地提出要求,但我完全没有选择,任何类型的输入都将不胜感激。


再问几句,果然和一遍遍调用rotate方法一样无聊。因为这只能(我认为)在 for 头中使用更多分号来完成,所以也许它们不被计算在内。

您可以使用Arrays.stream(int[],int,int) method two times to get two streams with the specified ranges of array: near and far, then swap and flatten them to one stream - return new array. Then you can use System.arraycopy方法将旧数组的内容替换为新数组的内容。带一个分号的长路径:

static void rotateByN(int[] arr, int n) {
    System.arraycopy(Stream
            .of(Arrays.stream(arr, n, arr.length),
                    Arrays.stream(arr, 0, n))
            .flatMapToInt(Function.identity())
            .toArray(), 0, arr, 0, arr.length);
}
public static void main(String[] args) {
    int[] arr = {2, 7, 6, 1, 0};
    rotateByN(arr, 3);
    System.out.println(Arrays.toString(arr)); // [1, 0, 2, 7, 6]
}

或者您可以使用Arrays.copyOfRange(int[],int,int)方法。思路是一样的:

static void rotateByN(int[] arr, int n) {
    System.arraycopy(Stream
            .of(Arrays.copyOfRange(arr, n, arr.length),
                    Arrays.copyOfRange(arr, 0, n))
            .flatMapToInt(Arrays::stream)
            .toArray(), 0, arr, 0, arr.length);
}

或者没有 streams 你可以使用 ArrayUtils.addAll(int[],int[]) 方法:

static void rotateByN(int[] arr, int n) {
    System.arraycopy(ArrayUtils.addAll(
            Arrays.copyOfRange(arr, n, arr.length),
            Arrays.copyOfRange(arr, 0, n)),
            0, arr, 0, arr.length);
}

你可以使用IntStream.concat method instead of Stream.of方法。

这稍微简化了代码:

static void rotateByN(int[] arr, int n) {
    System.arraycopy(IntStream
            .concat(Arrays.stream(arr, n, arr.length),
                    Arrays.stream(arr, 0, n))
            .toArray(), 0, arr, 0, arr.length);
}
public static void main(String[] args) {
    int[] arr = {2, 7, 6, 1, 0};
    rotateByN(arr, 3);
    System.out.println(Arrays.toString(arr)); // [1, 0, 2, 7, 6]
}

另请参阅: