ฉันจะย้อนกลับอาร์เรย์ int ใน Java ได้อย่างไร


238

ฉันพยายามที่จะย้อนกลับอาร์เรย์ int ใน Java

วิธีนี้จะไม่ย้อนกลับอาร์เรย์

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;
}

มีอะไรผิดปกติกับมัน?


31
ฉันเห็นสิ่งที่ฉันทำผิด ควรเป็น validData.length / 2 มิฉะนั้นจะกลับตัวเองแล้วยกเลิกการย้อนกลับตัวเอง
MichaelScott

4
ดูen.wikipedia.org/wiki/In-place_algorithmซึ่งมีคำอธิบายเวอร์ชั่นที่ถูกต้องของอัลกอริทึมนี้
Dean Povey

คำตอบ:


284

ในการย้อนกลับอาร์เรย์ 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;
}

ในแบบที่คุณทำคุณสลับแต่ละองค์ประกอบสองครั้งดังนั้นผลลัพธ์จะเหมือนกับรายการเริ่มต้น


และฉันต้องการที่จะมีvalidData.length / 2ส่วนร่วมกับด้านนอกของ for-loop
Jin Kwon

7
@ จินฉันจะไม่ มันทำให้สับสนกับความหมายเท่านั้นและฉันพนันได้เลยว่าผู้แปลที่เหมาะสมจะทำเพื่อคุณ ไม่ต้องคำนึงถึงว่าจะไม่มีประโยชน์ในการปรับขนาดเล็กจนกว่าคุณจะมีหลักฐานที่ชัดเจนจากการทำโปรไฟล์ว่าจำเป็น / มีประโยชน์
Nicu Stiurca

9
@JinKwon validData.length >> 1ที่จะเป็นประเภทชอบทำ มันเทียบเท่าและเร็วกว่า แต่ก็ทำให้โปรแกรมเมอร์หลายคนสับสนและคอมไพเลอร์ที่ดีก็จะทำเช่นนั้นโดยอัตโนมัติ
Justin

2
คุณควรทำการคำนวณนี้เพียงครั้งเดียวvalidData.length - i - 1และบันทึกลงในตัวแปร

ผู้ใดสามารถแนะนำการกลับรายการโดยใช้ตัวแปรชั่วคราว !!
sg28

303

ด้วยคอมมอนส์แลงคุณสามารถใช้

ArrayUtils.reverse(int[] array)

ส่วนใหญ่แล้วมันเร็วกว่าและปลอดภัยกว่าบั๊กที่ใช้กับห้องสมุดที่มีอยู่แล้วที่ใช้งานง่ายและผ่านการทดสอบจากผู้ใช้เมื่อพวกเขาดูแลปัญหาของคุณ


3
ฉันต้องการให้มันส่งคืนอาร์เรย์ (ส่งผ่าน) กลับสำหรับสไตล์การทำงานเหมือน
Laurent G

2
@ laurent-g เพื่อความเป็นธรรม: การย้อนกลับอาร์เรย์ด้วยวิธีนี้มีประสิทธิภาพของหน่วยความจำมากกว่าซึ่งอาจเป็นเหตุผลว่าทำไมพวกเขาถึงทำแบบนี้
Sirmyself

4
จุดของฉันไม่ได้คัดลอกหรือไม่คัดลอก ข้อความของฉันระบุว่า "(ผ่านแล้ว)" ที่จะส่งคืน (หลังจากกลับด้าน) ดังนั้นจึงสามารถส่งผ่านในนิพจน์โดยไม่ต้องการคำสั่งแยกต่างหาก
Laurent G

52
public class ArrayHandle {
    public static Object[] reverse(Object[] arr) {
        List<Object> list = Arrays.asList(arr);
        Collections.reverse(list);
        return list.toArray();
    }
}

11
แน่นอนมันจะ รายการสามารถเก็บได้เฉพาะ Objects ไม่ใช่แบบดั้งเดิมดังนั้น primitives ทั้งหมด ( ints ในกรณีนี้) จะถูกห่อด้วย wrappers ที่เกี่ยวข้อง ( Integers ในกรณีนี้) และวางไว้ในรายการ คุณเห็นว่าIntegerเป็นวัตถุ @Tom
11684

6
ระวัง: ถ้าฉันไม่ผิดอาเรย์ดั้งเดิมจะถูกปรับเปลี่ยน เพื่อให้ชัดเจนคุณอาจต้องการที่จะไม่คืนสิ่งใด
Andrea Zilio

3
@ 11684 ใช่รายการทั่วไปสามารถเก็บวัตถุได้เท่านั้น แต่วิธีการยกเว้นอาร์เรย์ อาร์เรย์สามารถเก็บดั้งเดิมได้ ดังนั้นจะแตกต่างจากint[] ลองใช้:Integer[] Integer[] array = new int[5]คุณจะได้รับข้อผิดพลาดในการรวบรวม นี่คือเหตุผลที่ArraysคลาสJava กำหนดวิธีการมากมายสำหรับการทำงานกับอาร์เรย์ดั้งเดิม พยายามที่จะผ่านวิธีการข้างต้นจะส่งผลให้ในสิ่งที่ต้องการint[] The method reverse(Object[]) in the type MakeSimple is not applicable for the arguments (int[])@Filip - อัลกอริทึมแบบแทนที่ใช้หน่วยความจำน้อยลงและทำงานได้เร็วขึ้น
Brian McCutchon

3
@Area จริง ๆ แล้วมันไม่ใช่ รายการที่ส่งคืนโดยArrays.asList()ไม่อ้างอิงอาเรย์ดั้งเดิมและไม่ส่งคืนอาเรย์ นั่นเป็นหนึ่งในปัญหาของวิธีนี้: มันใช้หน่วยความจำเพิ่มขึ้นสามเท่าและทำงานเป็นอัลกอริธึมแบบแทนที่
Brian McCutchon

4
วิธีการนี้อาจใช้งานได้ แต่มีวิธีการหนึ่งที่ไม่สามารถส่งค่าint[]อาร์กิวเมนต์ไปยังวิธีนี้ได้ ( "ประเภทที่เข้ากันไม่ได้: int [] ไม่สามารถแปลงเป็น Object []" )
MC Emperor

47
Collections.reverse(Arrays.asList(yourArray));

java.util.Collections.reverse()สามารถย้อนกลับjava.util.Listและjava.util.Arrays.asList()ส่งกลับรายการที่ล้อมอาร์เรย์เฉพาะที่คุณส่งไปให้ดังนั้นจึงyourArrayถูกย้อนกลับหลังจากการเรียกCollections.reverse()ใช้

ค่าใช้จ่ายเป็นเพียงการสร้างหนึ่งรายการวัตถุและไม่จำเป็นต้องมีห้องสมุดเพิ่มเติม

มีคำตอบที่คล้ายกันในคำตอบของ Tarik และผู้ให้ความเห็น แต่ฉันคิดว่าคำตอบนี้จะกระชับและแยกวิเคราะห์ได้ง่ายขึ้น


15
สำหรับอาร์เรย์ของวัตถุนี่เป็นทางออกที่ดี แต่มันใช้ไม่ได้กับอาร์เรย์ดั้งเดิม เช่น. การส่งผ่านint[]ไปยังasList(...)จะไม่ส่งคืน a List<Integer>แต่List<int[]>มีองค์ประกอบหนึ่งรายการ มี AFAICS ง่ายไม่มีตัวในทางที่จะแปลงไปยังint[] Integer[]
Martin Rust

4
สิ่งนี้จะไม่ทำงานกับอาร์เรย์ดั้งเดิม ... คอลเลกชัน dosnt คืนค่าดังนั้นตอนนี้คุณมีอาร์เรย์ที่ไร้ประโยชน์เป็นรายการในหน่วยความจำ
NightSkyCode

@MartinRust Java 8+: Arrays.stream(arr).boxed().collect(Collectors.toList())หรือArrays.stream(arr).boxed().toArray(Integer[]::new)
Simon Forsberg

39

ฉันคิดว่าการทำตามตรรกะของอัลกอริทึมง่ายขึ้นถ้าคุณประกาศตัวแปรที่ชัดเจนเพื่อติดตามดัชนีที่คุณสลับในการวนซ้ำในแต่ละรอบ

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;
    }
}

ฉันยังคิดว่ามันสามารถอ่านได้ง่ายขึ้นในการวนรอบในขณะนี้

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--;
    }
}

ลักษณะการแลกโรงเรียนเก่าขึ้นง่าย แต่ใช่เมื่อเกี่ยวข้องกับค่าดัชนีอาร์เรย์ซ้ายขวา ... จะเป็นประโยชน์สำหรับการดีบักถ้ามี
Srinath พระพิฆเนศวร

คุณสามารถเพิ่ม 'การแลกเปลี่ยนเป็นโมฆะคงที่สาธารณะ (int [] data, int index1, int index2) {... }' และใช้สิ่งนั้นจาก 'reverse' เช่นนี้: swap (data, left, right)
pm_

13

มีคำตอบมากมายอยู่ที่นี่แล้วส่วนใหญ่เน้นที่การปรับเปลี่ยนอาร์เรย์ในสถานที่ แต่เพื่อความสมบูรณ์นี่คืออีกวิธีหนึ่งในการใช้สตรีม Java เพื่อรักษาอาเรย์ดั้งเดิมและสร้างอาเรย์กลับด้านใหม่:

    int[] a = {8, 6, 7, 5, 3, 0, 9};
    int[] b = IntStream.rangeClosed(1, a.length).map(i -> a[a.length-i]).toArray();

10

ด้วยฝรั่ง:

Collections.reverse(Ints.asList(array));

4
มันยอดเยี่ยมมาก! สั้นและมีประสิทธิภาพ เช่นเดียวกับasListวิธีการทั้งหมดมันสร้างมุมมองที่เขียนโดยตรงไปยังอาร์เรย์การสำรองข้อมูล (ดั้งเดิม) ฉันคิดว่าผู้มีสิทธิ์ลงคะแนนเสียงที่นี่คิดผิดโดยคิดว่านี่ส่งคืนรายการที่บรรจุหรืออะไรบางอย่าง
ลุคอัชเชอร์วู้ด

@LukeUsherwood น่าจะมีค่าใช้จ่ายบางส่วนจากการชกมวยและการไม่ตีกล่องเมื่อเรียกรับและตั้งค่าในแต่ละองค์ประกอบ แต่ฉันเห็นด้วยกับคุณว่านี่เป็นทางออกที่ยอดเยี่ยม
Patrick Parker

แน่นอนว่ามันควรค่าแก่การรับรู้ ฉันไม่คิดว่ามันจะเป็นเรื่องใหญ่ในรหัสส่วนใหญ่ที่ฉันทำงานด้วย - พื้นที่ 'ร้อน' ของเรามีการกำหนดไว้อย่างดีส่วนที่เหลือคือ 'รหัสกาว' ของแปลก ๆ ในขณะเดียวกันฉันก็เห็นพ้องต้องกันว่าหน่วยความจำปั่นยังสร้างค่าใช้จ่ายเพิ่มเติม "ที่ซ่อนอยู่" ที่ผู้ทำโปรไฟล์ไม่ได้กำหนดให้กับฟังก์ชันจริง
ลุค Usherwood

@LukeUsherwood มันยังคงกลับรายการกล่องแทนที่จะเป็นอาร์เรย์พ
ริม

2
@AnthonyJClink ไม่แน่ใจว่า "มัน" หมายถึงอะไร แต่ยูทิลิตี้ JDK Collections.reverseเป็นวิธีการที่เป็นโมฆะ สิ่งนี้ทำงานในสถานที่ในคลาสภายในของ Guava ที่ล้อมรอบint[](เนื่องจากมันไม่เคยเก็บรายการของ boxed Integers ฉันจะไม่เรียก class ว่า "boxed list" แต่จะเป็น "List view of a array") แต่ใช่มันทำงานผ่านอินเทอร์เฟซที่ส่งผ่านIntegerวัตถุดังนั้นสิ่งนี้จะสร้างจำนวนมากของวัตถุชั่วคราวปั่นและมวยดังกล่าว ลองใช้IntStreamหรือไลบรารีรวบรวมแบบดั้งเดิมสำหรับประสิทธิภาพที่สำคัญ (Trove, Koloboke, Eclipse Collections, ... )
Luke Usherwood

10

ในกรณีของ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]

7

ง่ายสำหรับวง!

for (int start = 0, end = array.length - 1; start <= end; start++, end--) {
    int aux = array[start];
    array[start]=array[end];
    array[end]=aux;
}

4
ในอนาคตโปรดแจ้งให้ผู้ถามทราบถึงสิ่งที่พวกเขาทำไม่ถูกต้องและสิ่งที่คุณทำอย่างถูกต้อง
Kartik Chugh

1
เปลี่ยนstart <= endเป็นstart < end
Leonard Pauli


5
for(int i=validData.length-1; i>=0; i--){
  System.out.println(validData[i]);
 }

น่าเสียดายที่นี่เป็นคำตอบที่สะอาดที่สุดที่มีอยู่ที่นี่เพราะนักพัฒนาทุกคนจะรู้วิธีการทำและไม่จำเป็นต้องมีการติดตั้งแพ็คเกจเพิ่มเติม
HoldOffHunger

5

นี่คือวิธีที่ฉันจะแก้ไขมันเป็นการส่วนตัว เหตุผลที่อยู่เบื้องหลังการสร้างวิธี parametrized คืออนุญาตให้เรียงลำดับอาร์เรย์ใด ๆ ... ไม่ใช่แค่จำนวนเต็มของคุณ

ฉันหวังว่าคุณจะรวบรวมบางอย่างจากมัน

@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;
}

2
ไม่สามารถแก้ปัญหาดั้งเดิมโดยใช้แบบดั้งเดิม
Melinda Green

มีหลายวิธีในการแปลงไพรเมอร์เป็นวัตถุ ฉันมักจะแนะนำให้หลีกเลี่ยง prims ทุกที่ที่เป็นไปได้ใน java และฉันก็เชื่อว่าควรได้รับการสนับสนุน
AnthonyJClink

การแปลงอาเรย์ดั้งเดิมที่มีความยาวที่ไม่รู้จักเป็นอาเรย์อาจเป็นความคิดที่แย่มากโดยเฉพาะถ้าทำโดยไม่ทราบ Java ไม่ใช่ Smalltalk ดึกดำบรรพ์เป็นส่วนหนึ่งของภาษาและมีสถานที่ของพวกเขา ไม่สำคัญว่าเราจะไม่ชอบพวกเขาเราต้องยอมรับพวกเขาและใช้มันตามความเหมาะสม
Melinda Green

1
คุณไม่จำเป็นต้องคัดลอกอาร์เรย์Collections.reverse(asList(arraytoReverse)); return arrayToReverse;จริงๆ asListเป็นเพียง wrapper รอบ ๆ อาร์เรย์ดังนั้นอาร์เรย์เดิมจึงกลับด้าน
Radiodef

3

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
}

3
บางทีคุณอาจหมายถึงการแลกเปลี่ยนเป็นรหัสเทียมสำหรับการแลกเปลี่ยนแบบอินไลน์แทนที่จะเป็นวิธีการโทร แต่ถ้าไม่เช่นนั้นจะไม่ทำงาน Java ผ่านการอ้างอิงดังนั้นจึงเป็นไปไม่ได้ที่จะเขียนวิธีการแลกเปลี่ยนสำหรับตัวแปร
Dean Povey

ฉันหมายถึงวิธีใดก็ตามที่คุณจะได้ v [i] & v [j] เพื่อแลกเปลี่ยน ฉันทราบวิธีการเรียกใช้เมธอดใน java สำหรับวิธีการคุณสามารถทำอะไรบางอย่างเช่น swap (v, i ++, j--);
fastcodejava

1
คณบดีอาร์เรย์ validData เป็นวัตถุที่ส่งผ่านโดยการอ้างอิงดังนั้นวิธี swap () จะทำงานได้อย่างสมบูรณ์
Gaël Oberson

3

หากทำงานกับข้อมูลที่เป็นแบบดั้งเดิม (เช่น 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];
    }
}

1
น่ารักเกินไปที่จะใช้จริงในรหัสการผลิต แต่ก็สนุกดี เพื่อความน่ารักสูงสุดให้ใช้การดำเนินการ% = ดังนี้: array [i]% = array [len - i - 1], ฯลฯ
Melinda Green

คล้ายกัน แต่สั้นกว่านิดหน่อย:for (int m = x.length, i = --m / 2; ++i <= m;) { x[i] ^= x[m - i]; x[i] ^= x[m - i] ^= x[i]; }
Thomas Mueller

2

มันมีประสิทธิภาพมากที่สุดในการวนซ้ำแถวหลัง

ฉันไม่แน่ใจว่าคำตอบของแอรอนนี้จะทำให้การโทรนี้Collections.reverse(list);ไม่มีใครรู้หรือไม่?


การวนซ้ำไปหลังอาร์เรย์ต้องใช้อาร์เรย์ใหม่ ฉันชอบโซลูชันที่โพสต์ด้านบนที่ทำอินไลน์ย้อนกลับโดยไม่ต้องสร้างอาร์เรย์ใหม่
mmcdole

1
@Simucal ทำไมต้องสร้างอาร์เรย์ใหม่ แค่ทำซ้ำมันย้อนกลับ
Trejkaz


1
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]);
  }
}

1
ใช่ฉันได้ลองใช้โค้ดที่เหมือนกันและชัดเจนพร้อมกับเอาต์พุตคือ int [] a = {1,3,5,2,6,7}; สำหรับ (int i = a.length-1; i> = 0; i--) {System.out.print (a [i] + "");}} มันจะย้อนกลับอาร์เรย์จากดัชนีล่าสุดไปยังดัชนีแรก
Rocket_03

1

การทำเช่นนี้จะไม่เกิดความผิดพลาดมากขึ้นหรือไม่

    int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int[] temp = new int[intArray.length];
    for(int i = intArray.length - 1; i > -1; i --){
            temp[intArray.length - i -1] = intArray[i];
    }
    intArray = temp;

1

โซลูชันที่มีความซับซ้อนของเวลา (o) และความซับซ้อนของพื้นที่ 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--;
    }
}

เพียงแค่ FYI สิ่งนี้สามารถกลายเป็นคอมเพล็กซ์สำหรับลูปfor (int start = 0, end = array.length - 1; start < end; start++, end--) { ... }ได้
Tim Cooke

1

2 วิธีในการย้อนกลับอาร์เรย์

  1. ใช้สำหรับวนรอบและสลับองค์ประกอบจนถึงจุดกึ่งกลางด้วยความซับซ้อนของเวลาของ 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));

    }

  2. การใช้ฟังก์ชั่นในตัว (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]


3
คือIntsอะไร
CodingNow

@ CodeNow เป็นหนึ่งในคลาสตัวช่วยอรรถประโยชน์ของ Guava - ดูที่นี่
mrec

1
    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]); 
        }
    }

1

มีคำตอบที่ดีบางข้อด้านบน แต่นี่คือวิธีที่ฉันทำ:

public static int[] test(int[] arr) {

    int[] output = arr.clone();
    for (int i = arr.length - 1; i > -1; i--) {
        output[i] = arr[arr.length - i - 1];
    }
    return output;
}

0

ด้านล่างเป็นโปรแกรมที่สมบูรณ์ในการทำงานในเครื่องของคุณ

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]);
        }   
    }
}

สำหรับโปรแกรมที่ใช้ matrix จะเป็นแหล่งข้อมูลที่ดีผ่านลิงค์


0

การใช้โซลูชัน 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/


0
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;
} 

4
โปรดพิจารณาเพิ่มคำอธิบายให้กับคำตอบของคุณ คำตอบที่ใช้รหัสเท่านั้นจะไม่อธิบายอะไรเลย
rgettman

0

นี่คือการใช้งานที่ง่ายเพื่อย้อนกลับอาร์เรย์ประเภทใด ๆรวมทั้งการสนับสนุนเต็ม / บางส่วน

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));
 }
}

0

นี่คือสิ่งที่ฉันเกิดขึ้น:

// 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);

0

มีสองวิธีในการแก้ปัญหา:

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;
}

นอกจากนี้เราสามารถใช้ Collections API จาก Java เพื่อทำสิ่งนี้

Collections API ภายในใช้วิธีการย้อนกลับในพื้นที่เดียวกัน

โค้ดตัวอย่างสำหรับการใช้ Collections API เป็นดังนี้:

public static Integer[] reverseAnArrayWithCollections(Integer[] array) {
    List<Integer> arrayList = Arrays.asList(array);
    Collections.reverse(arrayList);
    return arrayList.toArray(array);
}


0
 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);

    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.