68

次のようなことをするよりも、配列内の2つの要素を交換するより効率的な方法があるかどうか疑問に思っています。

String temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;

まあ、これは明らかに悪いことでも間違っていることでもありませんが、私は頻繁に交換する必要があるので、これを行うためのより効率的な方法を提供するLibsまたは何かがあるかどうか興味がありますか?

4

13 に答える 13

36

いいえ。使用する場所ごとに簡潔にする関数を使用することもできますが、最終的には、実行される作業は同じになります(さらに、HotSpotがインラインに移動するまで、関数呼び出しのオーバーヘッドが発生します。 、関数を作成しますstatic final)。

于 2012-12-07T15:40:30.117 に答える
34

これにより、シームレスになります。

public static final <T> void swap (T[] a, int i, int j) {
  T t = a[i];
  a[i] = a[j];
  a[j] = t;
}

public static final <T> void swap (List<T> l, int i, int j) {
  Collections.<T>swap(l, i, j);
}

private void test() {
  String [] a = {"Hello", "Goodbye"};
  swap(a, 0, 1);
  System.out.println("a:"+Arrays.toString(a));
  List<String> l = new ArrayList<String>(Arrays.asList(a));
  swap(l, 0, 1);
  System.out.println("l:"+l);
}
于 2012-12-07T15:59:26.913 に答える
18

数値を交換していて、別の関数を作成したり、紛らわしいXORハックを使用したりせずにコードを簡潔に記述したい場合は、これがはるかに理解しやすく、ワンライナーでもあることがわかります。

public static void swap(int[] arr, int i, int j) {
    arr[i] = (arr[i] + arr[j]) - (arr[j] = arr[i]);
}

いくつかの原始的なベンチマークから私が見たのは、パフォーマンスの違いも基本的に無視できるということです。

これは、少なくとも整数の場合、一時変数を使用せずに配列要素を交換するための標準的な方法の1つです。

于 2017-01-28T15:13:46.867 に答える
11

文字列を交換したい場合。それはすでにそれを行うための効率的な方法です。

ただし、整数を交換する場合は、XORを使用して、次のように2つの整数をより効率的に交換できます。

int a = 1; int b = 2; a ^= b; b ^= a; a ^= b;
于 2012-12-07T15:41:46.790 に答える
5

使用Collections.swapArrays.asList

Collections.swap(Arrays.asList(arr), i, j);
于 2017-09-20T05:40:18.820 に答える
2

インプレーススワッピング(すでに知らなかった場合)は、一時変数を作成しないことで少しスペースを節約できます。

arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
于 2021-01-21T00:44:14.580 に答える
1

パーティーに非常に遅れていますが(私の謝罪)、ここで提供されているものよりも一般的なソリューションを実装できます(プリミティブと非プリミティブで同様に機能します):

public static void swap(final Object array, final int i, final int j) {
    final Object atI = Array.get(array, i);
    Array.set(array, i, Array.get(array, j));
    Array.set(array, j, atI);
}

コンパイル時の安全性は失われますが、うまくいくはずです。

注I:NullPointerException指定されたarraynullであるIllegalArgumentException場合、指定されたarrayものが配列でないArrayIndexOutOfBoundsException場合、およびいずれかのインデックスが指定されたに対して有効でない場合は、を取得しますarray

注II:配列タイプ(およびすべてのプリミティブ型)ごとObject[]に個別のメソッドを使用すると、いくつかのボックス化/アンボックス化が必要になるため、(ここに示す他のアプローチを使用して)パフォーマンスが向上します。しかし、それはまた、書く/維持するためのはるかに多くのコードになるでしょう。

于 2017-08-02T01:09:54.243 に答える
1

これを試して:

    int lowIndex = 0;
    int highIndex = elements.length-1;

    while(lowIndex < highIndex) {
        T lowVal = elements[lowIndex];
        T highVal = elements[highIndex];
        elements[lowIndex] = highVal;
        elements[highIndex] = lowVal;

        lowIndex += 1;
        highIndex -=1;
    }
于 2017-08-11T15:29:34.640 に答える
0

まずfor (int k = 0; k **<** data.length **- 1**; k++)、<はkが長さ-1になるまで続くため、記述しないでください。その後、ループは配列の最後の位置まで実行され、配列の最後の位置を取得しません。だからあなたは2つの方法でそれを修正することができます:1:for (int k = 0; k <= data.length - 1; k++) 2:for (int k = 0; k < data.length; k++)そしてそれはうまくいくでしょう!!! スワップするには、次を使用できます。intの1つを別の場所に保持してから、置き換える

int x = data[k]
data[k] = data[data.length - 1]
data[data.length - 1] = x;

intの1つを失いたくないからです!!

于 2019-04-24T19:14:22.057 に答える
0

オブジェクト型とプリミティブ型のソリューション:

public static final <T> void swap(final T[] arr, final int i, final int j) {
    T tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final boolean[] arr, final int i, final int j) {
    boolean tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final byte[] arr, final int i, final int j) {
    byte tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final short[] arr, final int i, final int j) {
    short tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final int[] arr, final int i, final int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final long[] arr, final int i, final int j) {
    long tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final char[] arr, final int i, final int j) {
    char tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final float[] arr, final int i, final int j) {
    float tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final double[] arr, final int i, final int j) {
    double tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
于 2019-06-15T21:49:39.277 に答える
0

これは単なる「ハック」スタイルの方法です。

int d[][] = new int[n][n];

static int swap(int a, int b) {
  return a;
}
...

in main class --> 

d[i][j + 1] = swap(d[i][j], d[i][j] = d[i][j + 1])
于 2020-08-11T01:34:28.000 に答える
0
public static final void swap (int[] a, int i, int j) {
    a[i] = a[i] + a[j];
    a[j] = a[i] - a[j];
    a[i] = a[i] - a[j];
}
于 2021-09-22T10:03:47.460 に答える
-3
public class SwapElements {

public static void main(String[] args) {

    int[] arr1 = new int[5];
    int[] arr2 = {10,20,30,40};

    System.out.println("arr1 Before Swapping " + Arrays.toString(arr1));
    System.out.println("arr2 Before Swapping " + Arrays.toString(arr2));

    int temp[];
    arr1[3] = 5;
    arr1[0] = 2;
    arr1[1] = 3;
    arr1[2] = 6;
    arr1[4] = 10;

    temp = arr1;
    arr1 = arr2;
    arr2 = temp;
    System.out.println("arr1 after Swapping " + Arrays.toString(arr1));
    System.out.println("arr2 after Swapping " + Arrays.toString(arr2));
}

}

于 2020-02-12T03:00:42.250 に答える