Napisy, konwersja StringBuilder to char;

0

Mam takie zadanko

Wygeneruj napis składający się z samych liter a lub b o długości
podanej wcześniej od użytkownika. Napis musi zostać wygenerowany tak,
żeby różnica w ilości wystąpień liter b oraz a w napisie nie była
większa niż 1. Następnie zmodyfikuj napis w taki sposób, żeby kolejne
litery a i b występowały na przemian. Na przykład na początku
wygenerowano napis abbbaaba, a po modyfikacji otrzymano abababab.

Poniżej jest mój kod, który nawet działa :D Jednak moje rozwiązanie jest za bardzo "Pokręcone" :)
Chodzi o to, że moje rozwiązanie, które modyfikuje tekst tak aby literki były naprzemian składa się z 5 metod w tym wielu pętli i warunków.

Pomysł na jakieś "normalne" rozwiązanie ?? ;)



import java.util.Random;
import java.util.Scanner;

public class Zad9 {

    static void randomString() {

        Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        int strinSize;
        String napis;

        System.out.println("Podaj długość napisu: ");
        strinSize = sc.nextInt();

        char[] arr = new char[strinSize];

        for (int i = 0; i < strinSize / 2; i++) {
            sb.append('a');
        }

        for (int i = strinSize / 2; i < strinSize; i++) {

            sb.append('b');
        }

        //Wymieszanie tablicy
        napis = shuffle(sb.toString().toCharArray());

        System.out.println("Tablica po wymieszaniu " + napis);

        //Uruchomienie metody ustawiającej znaki naprzemian
        napis = ababa(sb.toString().toCharArray());

        System.out.println("Napis wynikowy: " + napis);
    }


    static String ababa(char[] arr) {

        if (arr.length % 2 == 0) {
            schuffleArrForEvenSize(arr, 'a');
        } else
            schuffleArrForOddSize(arr);

        return new String(arr);
    }


    static void schuffleArrForOddSize(char[] arr) {

        int a = 0;
        int b = 0;

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 'a')
                a++;
            else b++;
        }

        if (a > b) {
            schuffleArrForEvenSize(arr, 'a');
        } else schuffleArrForEvenSize(arr, 'b');

    }


    static void schuffleArrForEvenSize(char[] arr, char startLetter) {

        int index;
        char lookinletter;

        for (int i = 0; i < arr.length; i++) {
            if (i % 2 == 0) {
                if (arr[i] != startLetter) {
                    index = lookingLetter(arr, startLetter, i + 1);
                    swap(arr, i, index);
                }
            } else {
                if (arr[i] == startLetter) {
                    if (startLetter == 'a') {
                        lookinletter = 'b';
                    } else
                        lookinletter = 'a';
                    index = lookingLetter(arr, lookinletter, i + 1);
                    swap(arr, i, index);
                }
            }
        }
    }


    static int lookingLetter(char[] arr, char letter, int startIndex) {
        int index = -1;

        for (int i = startIndex; i < arr.length; i++) {
            if (arr[i] == letter) {
                index = i;
            }
        }
        return index;
    }


    static String shuffle(char[] arr) {

        Random rd = new Random();

        for (int i = arr.length; i > 1; i--) {
            swap(arr, i - 1, rd.nextInt(i));
        }

        return new String(arr);
    }

    static void swap(char[] arr, int i, int j) {

        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

    }


    public static void main(String[] args) {
        randomString();
    }

}


P.S. Macie też tak, że jak już raz wpadniecie w jakiś sposób myślenia o danym problemie to później już strasznie ciężko jest spojrzeć na niego z innej perspektywy??

0

Jeśli dobrze rozumiem zadanie, to wystarczy coś takiego:

    private static String generateWithOrder(char start, int length) {
        return IntStream.iterate(start, previous -> previous == 'a' ? 'b' : 'a')
            .limit(length)
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString();
    }

    private static String generateWithoutOrder(int length, Random random) {
        int numberOfA = length / 2;
        int numberOfB = length - numberOfA;
        IntStream aStream = IntStream.generate(() -> 'a').limit(numberOfA);
        IntStream bStream = IntStream.generate(() -> 'b').limit(numberOfB);
        return IntStream.concat(aStream, bStream)
            .boxed()
            .sorted(Comparator.comparingInt(i -> random.nextInt()))
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
    }
}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.