Bir qatorni teskari aylantirish uchun "Recursion" dan foydalanish

Men o'zimdan so'zni so'z bilan qaytarib yozmoqchiman. (Misol: "Salom do'stim" "do'stim salom" deb o'zgartirildi) Bu men uchun bu usulni yozishga uringan kod. Men bir nechta shunga o'xshash o'zgarishlarni sinab ko'rdim, ammo chiqish faqat Stringning birinchi yoki oxirgi so'zidir. O'ylaymanki, bu "buzilgan" qism - bu birinchi ifodadir, ammo ishonchim komil emas.

public static String reverse (String words) {
   Scanner sc = new Scanner(words);
   String backwards = "";

   if (sc.hasNext()) {
     String currentWord = sc.next();
     reverse(sc.nextLine());
     backwards = backwards + " " + currentWord;
   } //end if
   else {
     backwards = words;
   } //end else

   return backwards;
 }

Men shunga o'xshash bir nechta savol borligini bilaman, ammo ularning javoblari xatolarimni tushunishimga yordam bermagan ko'rinadi.

Rahmat!

1
@Gabbie istayman, agar senga stringbuilder bilan yechim berishi mumkin.
qo'shib qo'ydi muallif Aominè, manba
O'zingizning takroriy qo'ng'iroqingiz natijasini saqlamaysiz.
qo'shib qo'ydi muallif Jorn Vernee, manba
Men buni bir nazar, rahmat qilaman! @JornVernee
qo'shib qo'ydi muallif Gabbie, manba
Men StringBuilder bilan ko'p ishlamadim, men unga qarayman! @OusmaneDiaw
qo'shib qo'ydi muallif Gabbie, manba
@OsmaneDiaw Albatta! Men buni qadrlayman :)
qo'shib qo'ydi muallif Gabbie, manba

6 javoblar

nextLine() deb nomlash kerak emas, chunki sizning kirishingiz bir satrda. Agar siz oddiy yordamchi usulni yaratib boshlasangiz, sizning mantiqingiz aniqroq bo'ladi, u so'zlari va pozitsiyani olishi kerak; u yerdan siz o'zingiz istagan mahsulotni o'zingiz kabi yaratishingiz mumkin

private static String reverse(String[] words, int p) {
    if (p + 1 < words.length) {
        return reverse(words, p + 1) + " " + words[p];
    } else if (p < words.length) {
        return words[p];
    }
    return "";
}

Keyin public usulini amalga oshirish oson, faqat 0 dan boshlangan teskari qo'ng'iroq qiling, faqat split > ( return natija uchun eslab qoling). Kabi,

public static String reverse(String words) {
    return reverse(words.split("\\s+"), 0);
}

Va keyin, men uni sinab ko'rdim

public static void main(String[] args) {
    System.out.println(reverse("Hello my friend"));
}

Qanday ezilgan (so'ralgan)

friend my Hello

Alternatively, you could make that helper take your Scanner instead like

private static String reverse(Scanner sc) {
    if (sc.hasNext()) {
        String currentWord = sc.next();
        if (sc.hasNext()) {
            return reverse(sc) + " " + currentWord;
        }
        return currentWord;
    }
    return "";
}

Va keyin sizning ochiq usulingiz

public static String reverse(String words) {
    return reverse(new Scanner(words));
}
4
qo'shib qo'ydi

Agar Scanner ishlatish o'rniga String.split so'zlarni birinchi bo'shliq atrofida bo'laklash uchun ortiqcha yuk ishlatishingiz mumkin:

public static String reverse(String words) {
    String[] wordArr = words.split(" ", 2);//split into a maximum of 2 Strings

    if (wordArr.length > 1) {//If there is more than 1 word
       //return the first word (wordArr[0]),
       //behind the reverse of the rest of the String (wordArr[1])
        return reverse(wordArr[1]) + " " + wordArr[0];
    }

    return wordArr[0];//else, just return the one word
}
3
qo'shib qo'ydi
Bu mening muammomni hal qildi va sodda va tushunarli edi, rahmat! :)
qo'shib qo'ydi muallif Gabbie, manba

O'zingizning rekvizitsiya natijalarini tashlaysiz:

 reverse(sc.nextLine());
 backwards = backwards + " " + currentWord;

Buning o'rniga, quyidagilarni foydalaning:

 backwards = reverse(sc.nextLine());
 backwards = backwards + " " + currentWord;

Yaxshiroq:

 backwards = reverse(sc.nextLine()) + " " + currentWord;
1
qo'shib qo'ydi
Muammolarni MCVE bilan yuborishingiz mumkin bo'lsa, men unga qarayman. Sizning joriy kodingiz muammoni hal qilish uchun etarli emas.
qo'shib qo'ydi muallif Prune, manba
Men buni oldim deb o'ylayman. Siz keyingi liniyani qidirib, hozirgi liniyaning qolgan qismini tekshirib bo'lmaydi. TA'MINOT: boshqalar taklif qilganidek, skanerni butunlay tashlab yuboring va mag'lubiyat paketlari bilan shug'ullaning. Keyingi joyni toping, u nuqtada ikkita pastki qatorga bo'linib, qolgan qismini qaytaring.
qo'shib qo'ydi muallif Prune, manba
Men bu taklifni sinab ko'rdim va nima uchun NoSuchElementException, har qanday fikrni olaman?
qo'shib qo'ydi muallif Gabbie, manba

Izohlarda aytib o'tilganidek, siz dan foydalanishingiz mumkin. > StringBuilder ni tanlang.

Ushbu misol xuddi shu so'zlarni yuboradi, usuli kiritilganda har bir bo'shliq bilan ularni ajratadi va keyingi iteratsiya uchun qo'shiladigan so'z indeksini yuborasiz.

Misol uchun:

public class RecursiveReverse {

    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) {
        String stringToReverse = "Hello my friend!";
        System.out.println(reverse(stringToReverse, stringToReverse.split(" ").length - 1));
    }

    public static String reverse(String words, int i) {
        if (i >= 0) { //If the index of the words is greater or equals the first word
            sb.append(words.split(" ")[i]); //We split it and append it to our StringBuilder
            sb.append(" "); //We append a space
            reverse(words, --i); //We do this again
        }
        return sb.toString(); //When the above condition doesn't match we return the StringBuilder object as a String (which contains the words reversed)
    }
}

Qaysi ushbu chiqim ishlab chiqaradi:

friend! my Hello 

Yaxshiroq uslub String majmuasidan parametr sifatida o'tadi, shuning uchun siz faqat bir marta (so'zlarni uslubga uslub sifatida yuborish vaqtida) Stringni ajratasiz.

public class RecursiveReverse {

    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) {
        String stringToReverse = "Hello my friend!";
        String words[] = stringToReverse.split(" ");
        System.out.println(reverse(words, words.length - 1));
    }

    public static String reverse(String words[], int i) {
        if (i >= 0) {
            sb.append(words[i]);
            sb.append(" ");
            reverse(words, --i);
        }
        return sb.toString();
    }
}
1
qo'shib qo'ydi

Akkumulyatordagi qo'ng'iroqlar o'rtasida chiqarilgan so'zlarni ushlab turishingiz kerak. Mana bir misol.

public static String reverse(String words, String acc){
    Scanner sc = new Scanner(words);

    if(!sc.hasNext()){
        return acc;
    }

    return reverse(sc.nextLine(), acc) + " " + sc.next();
}

Siz buni shunday chaqirasiz.

reverse("Hello my friend", "");

Dunyoda eng samarali dastur emas, balki ha ... Bu ish kerak!

Keyinchalik samarali ishlamoqchi bo'lsangiz, akkumulyator sifatida StringBuilder dan foydalaning.

0
qo'shib qo'ydi

O'zingizni takrorlashingiz kerakmi? Buni bo'lmasdan qilishingiz mumkin.

public static String reverse(String words) {
    String[] list = words.split(" ");
    Collections.reverse(list);
    String reversed = String.join(" ", list);
    return reversed;
}
0
qo'shib qo'ydi
Kirish uchun rahmat, lekin men recursiondan foydalanishim kerak :)
qo'shib qo'ydi muallif Gabbie, manba