Javaでint配列を反転しようとしています。
このメソッドは配列を反転しません。
for(int i = 0; i < validData.length; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
それの何が問題になっていますか?
Javaでint配列を反転しようとしています。
このメソッドは配列を反転しません。
for(int i = 0; i < validData.length; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
それの何が問題になっていますか?
回答:
次のように、int配列を反転するには、中点に到達するまでアイテムを交換します。
for(int i = 0; i < validData.length / 2; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
あなたがそれをしている方法では、各要素を2回交換するので、結果は最初のリストと同じです。
validData.length / 2
、forループの外側に部品を入れたいと思います。
validData.length >> 1
です。これは同等で高速ですが、多くのプログラマを混乱させ、優れたコンパイラは自動的にそれを実行します。
ではCommons.Lang、あなたは単に使用することができます
ArrayUtils.reverse(int[] array)
ほとんどの場合、問題を処理するときに、すでにユニットテストとユーザーテストが行われている簡単に利用できるライブラリを使用するほうが、より速く、より安全です。
public class ArrayHandle {
public static Object[] reverse(Object[] arr) {
List<Object> list = Arrays.asList(arr);
Collections.reverse(list);
return list.toArray();
}
}
int
この場合はs)はそれぞれのラッパー(Integer
この場合はs )にラップされ、リストに入れられます。ご覧Integer
のとおり、sはオブジェクトです。@トム
int[]
とは異なりInteger[]
ます。試してみてくださいInteger[] array = new int[5]
。コンパイルエラーが発生します。これが、Java Arrays
クラスがプリミティブ配列を操作するための一連のメソッドを定義する理由です。int[]
上記のメソッドにを渡そうとすると、のような結果になりThe method reverse(Object[]) in the type MakeSimple is not applicable for the arguments (int[])
ます。@Filip-インプレースアルゴリズムは、より少ないメモリを使用し、より高速に実行されます。
Arrays.asList()
元の配列を参照せず、返される配列も参照しません。これはこの方法の問題の1つです。メモリを3倍に使用し、インプレースアルゴリズムとして作業を3倍にします。
int[]
ありますが、このメソッドに引数としてを渡すことはできません(「互換性のない型:int []はObject []に変換できません」)。
Collections.reverse(Arrays.asList(yourArray));
java.util.Collections.reverse()
はjava.util.List
sを逆にjava.util.Arrays.asList()
して、渡した特定の配列をラップするリストを返すためyourArray
、の呼び出し後に逆になりますCollections.reverse()
。
コストは1つのListオブジェクトを作成するだけで、追加のライブラリは必要ありません。
同様の解決策がTarikとそのコメントの回答にも示されていますが、この回答はより簡潔で、より簡単に解析できると思います。
int[]
to asList(...)
を渡すとは返されませんList<Integer>
が、List<int[]>
1つの要素を含むが返されます。AFAICSには、int[]
をに変換する単純な組み込みの方法はありませんInteger[]
。
Arrays.stream(arr).boxed().collect(Collectors.toList())
またはArrays.stream(arr).boxed().toArray(Integer[]::new)
ループの各反復でスワップしているインデックスを追跡するために明示的な変数を宣言すると、アルゴリズムのロジックに従う方が少し簡単になると思います。
public static void reverse(int[] data) {
for (int left = 0, right = data.length - 1; left < right; left++, right--) {
// swap the values at the left and right indices
int temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
また、これをwhileループで行う方が読みやすいと思います。
public static void reverse(int[] data) {
int left = 0;
int right = data.length - 1;
while( left < right ) {
// swap the values at the left and right indices
int temp = data[left];
data[left] = data[right];
data[right] = temp;
// move the left and right index pointers in toward the center
left++;
right--;
}
}
ここにはすでに多くの答えがあり、主に配列をその場で変更することに焦点を当てています。ただし、完全を期すために、Javaストリームを使用して元の配列を保持し、新しい反転配列を作成する別のアプローチを次に示します。
int[] a = {8, 6, 7, 5, 3, 0, 9};
int[] b = IntStream.rangeClosed(1, a.length).map(i -> a[a.length-i]).toArray();
グアバで:
Collections.reverse(Ints.asList(array));
asList
メソッドと同様に、バッキング(プリミティブ)配列に直接書き込むビューを作成します。ここの反対投票者は、これが箱入りのリストか何かを返したと誤って考えたと思います。
Collections.reverse
はvoidメソッドです。これは、をラップするGuava内部クラスでインプレースで動作しますint[]
(ボックス化されたInteger
sのリストを格納することはないため、クラスを「ボックス化リスト」と呼ぶのではなく、「配列のリストビュー」と呼びます)。しかし、はいInteger
、オブジェクトを渡すインターフェイスを介して動作するため、前述のように、一時的なオブジェクトのチャーンとボクシングが大量に発生します。IntStream
パフォーマンスが重要な場合は、またはプリミティブコレクションライブラリを試してください。(Trove、Koloboke、Eclipseコレクションなど)
Java 8の場合、IntStream
次のように整数の配列を逆にするためにも使用できます。
int[] sample = new int[]{1,2,3,4,5};
int size = sample.length;
int[] reverseSample = IntStream.range(0,size).map(i -> sample[size-i-1])
.toArray(); //Output: [5, 4, 3, 2, 1]
単純なforループ!
for (int start = 0, end = array.length - 1; start <= end; start++, end--) {
int aux = array[start];
array[start]=array[end];
array[end]=aux;
}
start <= end
へstart < end
これはあなたを助けます
int a[] = {1,2,3,4,5};
for (int k = 0; k < a.length/2; k++) {
int temp = a[k];
a[k] = a[a.length-(1+k)];
a[a.length-(1+k)] = temp;
}
for(int i=validData.length-1; i>=0; i--){
System.out.println(validData[i]);
}
これは私が個人的に解決する方法です。パラメータ化されたメソッドを作成する背後にある理由は、整数だけでなく、配列をソートできるようにするためです。
あなたはそれから何かを集めることを望みます。
@Test
public void reverseTest(){
Integer[] ints = { 1, 2, 3, 4 };
Integer[] reversedInts = reverse(ints);
assert ints[0].equals(reversedInts[3]);
assert ints[1].equals(reversedInts[2]);
assert ints[2].equals(reversedInts[1]);
assert ints[3].equals(reversedInts[0]);
reverseInPlace(reversedInts);
assert ints[0].equals(reversedInts[0]);
}
@SuppressWarnings("unchecked")
private static <T> T[] reverse(T[] array) {
if (array == null) {
return (T[]) new ArrayList<T>().toArray();
}
List<T> copyOfArray = Arrays.asList(Arrays.copyOf(array, array.length));
Collections.reverse(copyOfArray);
return copyOfArray.toArray(array);
}
private static <T> T[] reverseInPlace(T[] array) {
if(array == null) {
// didn't want two unchecked suppressions
return reverse(array);
}
Collections.reverse(Arrays.asList(array));
return array;
}
Collections.reverse(asList(arraytoReverse)); return arrayToReverse;
。asList
は配列のラッパーにすぎないため、元の配列は逆になります。
プログラムはでのみ機能しlength = 0, 1
ます。あなたが試すことができます :
int i = 0, j = validData.length-1 ;
while(i < j)
{
swap(validData, i++, j--); // code for swap not shown, but easy enough
}
よりプリミティブなデータ(char、byte、intなど)を扱う場合は、楽しいXOR演算を実行できます。
public static void reverseArray4(int[] array) {
int len = array.length;
for (int i = 0; i < len/2; i++) {
array[i] = array[i] ^ array[len - i - 1];
array[len - i - 1] = array[i] ^ array[len - i - 1];
array[i] = array[i] ^ array[len - i - 1];
}
}
for (int m = x.length, i = --m / 2; ++i <= m;) { x[i] ^= x[m - i]; x[i] ^= x[m - i] ^= x[i]; }
単純に配列を逆方向に反復することが最も効率的です。
アーロンのソリューションがこのviをこの呼び出しで実行するCollections.reverse(list);
かどうかはわかりませんが、誰か知っていますか?
public void display(){
String x[]=new String [5];
for(int i = 4 ; i > = 0 ; i-- ){//runs backwards
//i is the nums running backwards therefore its printing from
//highest element to the lowest(ie the back of the array to the front) as i decrements
System.out.println(x[i]);
}
}
o(n)時間の複雑さとo(1)空間の複雑さのあるソリューション。
void reverse(int[] array) {
int start = 0;
int end = array.length - 1;
while (start < end) {
int temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end--;
}
}
for (int start = 0, end = array.length - 1; start < end; start++, end--) { ... }
。
配列を逆にする2つの方法。
Forループを使用し、O(n / 2)の時間の複雑さで中点まで要素を交換します。
private static void reverseArray() {
int[] array = new int[] { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < array.length / 2; i++) {
int temp = array[i];
int index = array.length - i - 1;
array[i] = array[index];
array[index] = temp;
}
System.out.println(Arrays.toString(array));
}
組み込み関数の使用(Collections.reverse())
private static void reverseArrayUsingBuiltInFun() {
int[] array = new int[] { 1, 2, 3, 4, 5, 6 };
Collections.reverse(Ints.asList(array));
System.out.println(Arrays.toString(array));
}
出力:[6、5、4、3、2、1]
Ints
?
以下は、マシンで実行する完全なプログラムです。
public class ReverseArray {
public static void main(String[] args) {
int arr[] = new int[] { 10,20,30,50,70 };
System.out.println("reversing an array:");
for(int i = 0; i < arr.length / 2; i++){
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
配列を使用する行列のプログラムの場合、これは良いソースになります。リンクをたどってください。
XORソリューションを使用して、コードが次のようになるはずの一時変数を回避する
for(int i = 0; i < validData.length; i++){
validData[i] = validData[i] ^ validData[validData.length - i - 1];
validData[validData.length - i - 1] = validData[i] ^ validData[validData.length - i - 1];
validData[i] = validData[i] ^ validData[validData.length - i - 1];
}
より良い説明はこのリンクを見てください:
http://betterexplained.com/articles/swap-two-variables-using-xor/
private static int[] reverse(int[] array){
int[] reversedArray = new int[array.length];
for(int i = 0; i < array.length; i++){
reversedArray[i] = array[array.length - i - 1];
}
return reversedArray;
}
ここでの逆配列に単純な実装であり、任意の型、プラスフル/部分的にサポート。
import java.util.logging.Logger;
public final class ArrayReverser {
private static final Logger LOGGER = Logger.getLogger(ArrayReverser.class.getName());
private ArrayReverser () {
}
public static <T> void reverse(T[] seed) {
reverse(seed, 0, seed.length);
}
public static <T> void reverse(T[] seed, int startIndexInclusive, int endIndexExclusive) {
if (seed == null || seed.length == 0) {
LOGGER.warning("Nothing to rotate");
}
int start = startIndexInclusive < 0 ? 0 : startIndexInclusive;
int end = Math.min(seed.length, endIndexExclusive) - 1;
while (start < end) {
swap(seed, start, end);
start++;
end--;
}
}
private static <T> void swap(T[] seed, int start, int end) {
T temp = seed[start];
seed[start] = seed[end];
seed[end] = temp;
}
}
これは対応する単体テストです
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;
public class ArrayReverserTest {
private Integer[] seed;
@Before
public void doBeforeEachTestCase() {
this.seed = new Integer[]{1,2,3,4,5,6,7,8};
}
@Test
public void wholeArrayReverse() {
ArrayReverser.<Integer>reverse(seed);
assertThat(seed[0], is(8));
}
@Test
public void partialArrayReverse() {
ArrayReverser.<Integer>reverse(seed, 1, 5);
assertThat(seed[1], is(5));
}
}
これが私が思いついたものです:
// solution 1 - boiler plated
Integer[] original = {100, 200, 300, 400};
Integer[] reverse = new Integer[original.length];
int lastIdx = original.length -1;
int startIdx = 0;
for (int endIdx = lastIdx; endIdx >= 0; endIdx--, startIdx++)
reverse[startIdx] = original[endIdx];
System.out.printf("reverse form: %s", Arrays.toString(reverse));
// solution 2 - abstracted
// convert to list then use Collections static reverse()
List<Integer> l = Arrays.asList(original);
Collections.reverse(l);
System.out.printf("reverse form: %s", l);
問題を解決するには2つの方法があります。
1.空間で配列を反転します。
手順1.開始インデックスと終了インデックスの要素を交換します。
手順2.開始インデックスをインクリメントして、終了インデックスをデクリメントします。
ステップ3.開始インデックス<終了インデックスまでステップ1とステップ2を繰り返す
このため、時間の複雑度はO(n)になり、空間の複雑度はO(1)になります。
空間で配列を逆にするサンプルコードは次のようになります。
public static int[] reverseAnArrayInSpace(int[] array) {
int startIndex = 0;
int endIndex = array.length - 1;
while(startIndex < endIndex) {
int temp = array[endIndex];
array[endIndex] = array[startIndex];
array[startIndex] = temp;
startIndex++;
endIndex--;
}
return array;
}
2.補助配列を使用して配列を反転します。
手順1.指定された配列と同じサイズの新しい配列を作成します。
ステップ2.開始インデックスから開始して、指定された配列から終了インデックスから開始して、新しい配列に要素を挿入します。
このため、時間の複雑度はO(n)になり、空間の複雑度はO(n)になります。
補助配列で配列を逆にするためのサンプルコードは次のようになります。
public static int[] reverseAnArrayWithAuxiliaryArray(int[] array) {
int[] reversedArray = new int[array.length];
for(int index = 0; index < array.length; index++) {
reversedArray[index] = array[array.length - index -1];
}
return reversedArray;
}
また、JavaのコレクションAPIを使用してこれを行うこともできます。
コレクションAPIは、内部で同じ逆空間アプローチを使用します。
コレクションAPIを使用するためのサンプルコードは次のとおりです。
public static Integer[] reverseAnArrayWithCollections(Integer[] array) {
List<Integer> arrayList = Arrays.asList(array);
Collections.reverse(arrayList);
return arrayList.toArray(array);
}
public static int[] reverse(int[] array) {
int j = array.length-1;
// swap the values at the left and right indices //////
for(int i=0; i<=j; i++)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
j--;
}
return array;
}
public static void main(String []args){
int[] data = {1,2,3,4,5,6,7,8,9};
reverse(data);
}
public static void main(String args[]) {
int [] arr = {10, 20, 30, 40, 50};
reverse(arr, arr.length);
}
private static void reverse(int[] arr, int length) {
for(int i=length;i>0;i--) {
System.out.println(arr[i-1]);
}
}