Реверс массива типа String с сохранением длины элементов

Только изучаю Java, и напал на задачку, к которой никак не подберусь. Условие следующее:

Given an array of strings, reverse them and their order in such way that their length stays the same as the length of the original inputs. Example:

Input:

{"Don't", "worry", ",", "be", "happy", "!"}

Output:

{"!yppa", "heb,y", "r", "ro", "wt'no", "D"}

Моя вариация решения:

public class ArrayReverser {
    public static String[] reverse(String[] a) {
        for (int j = 0; j < a.length; j++) {
            char[] charArray = a[j].toCharArray();
            String resultString = "";
            for (int i = charArray.length - 1; i >= 0; i--) {
                resultString += charArray[i];

            }
            a[j] = resultString;
        }
        return a;
    }
}

Ошибка:

Result should be [!dneirf, ym, ,ava, J, ot, emocle, W]
 for input [Welcome, to, Java, ,, my, friend, !]
: arrays first differed at element [0]; expected:<[!dneirf]> but was:<[emocleW]>
    at org.junit.internal.ComparisonCriteria.arrayEquals(ComparisonCriteria.java:78)
    at org.junit.internal.ComparisonCriteria.arrayEquals(ComparisonCriteria.java:28)
    at org.junit.Assert.internalArrayEquals(Assert.java:534)
    at org.junit.Assert.assertArrayEquals(Assert.java:285)
    at ArrayReverserTest.arrayReverser_positiveTest(ArrayReverserTest.java:12)
    ... 51 trimmed
Caused by: org.junit.ComparisonFailure: expected:<[!dneirf]> but was:<[emocleW]>
    at org.junit.Assert.assertEquals(Assert.java:117)
    at org.junit.Assert.assertEquals(Assert.java:146)
    at org.junit.internal.ExactComparisonCriteria.assertElementsEqual(ExactComparisonCriteria.java:8)
    at org.junit.internal.ComparisonCriteria.arrayEquals(ComparisonCriteria.java:76)
    ... 56 more

Ответы (3 шт):

Автор решения: Vittiv

Ты переворачиваешь каждое слово, а надо всю строку. Пройди по входному массиву строк, сохраняя длину каждого слова в отдельный интовый массив длин, превращая строки в массивы char и складывая их подряд в единый массив char.

Потом бери с конца единого массива количество char, соответствующее длине первого слова из массива длин и по одному символу пиши в строку, эту строку пиши в результирующий массив строк.

Можно сразу формировать единый массив char, записывая в перевернутые слова в него.

Еще можно брать длину первого слова и отсчитывать с конца для него буквы, но так сложнее писать и легче ошибиться, надо учитывать длину слов в конце массива строк и брать необходимое количество. С единым массивом char проще.

Или так можно:

    String[] in = {"Welcome", "to", "the", "Moon", "!"};
    int arrLength = in.length;
    StringBuilder sb = new StringBuilder();
    int[] count = new int[arrLength];
    int i = 0;
    for (String s: in) {
        sb.append(s);        //"WelcometotheMoon!"
        count[i]=s.length(); // 7, 2, 3, 4, 1
        i++;
    }
    sb.reverse();            //"!nooMehtotemocleW"

    String[] res = new String[arrLength];
    int start = 0;
    for (int j = 0; j < arrLength; j++) {
        res[j] = sb.substring(start, start + count[j]);
        start += count[j];
        System.out.print(res[j] + " ");  // "!nooMeh" "to" "tem" "ocle" "W"
    }

}
→ Ссылка
Автор решения: Дмитрий

Если в лоб, то можно так:

public static String[] reverse(String[] inputArr) {
    return Stream.of(inputArr)
            .collect(StringBuilder::new, (sb, s) -> sb.append(s).append(" "), StringBuilder::append)
            .reverse().toString().trim().split(" ");
}
→ Ссылка
Автор решения: Олексій Моренець
String[] inputArr = {"Don't", "worry", ",", "be", "happy", "!"};
String[] resultArr = new String[inputArr.length];
Character[] chars = Stream.of(inputArr)
               .flatMapToInt(CharSequence::chars)
               .mapToObj(i -> (char) i)
               .toArray(Character[]::new);
int pos = chars.length - 1;
for (int j = 0; j < inputArr.length; j++) {
    String s = inputArr[j];
    resultArr[j] = "";
    for (int i = 0; i < s.length(); i++) {
        resultArr[j] += chars[pos--];
    }
}
// output: [!yppa, heb,y, r, ro, wt'no, D]
System.out.println(Arrays.toString(resultArr));
→ Ссылка