Regex - Modyfikowanie ciągu znaku na podstawie wzorca

Odpowiedz Nowy wątek
2019-05-31 11:47
0

Treść Zadania

Stosując wyrażenia regularne pobieraj od użytkownika napis dopóki nie będzie składał się z trzech wyrazów
o długościach dokładnie 10 znaków. Pierwszy wyraz ma zawierać same duże litery. Drugi wyraz ma zawierać
same małe litery, trzeci wyraz ma zawierać same cyfry. Napis wynikowy ma powstać poprzez zamianę znaków
napisu trzeciego na odpowiednich pozycjach z literami pierwszego napisu, kiedy rozpatrujemy znaki
na pozycjach parzystych oraz poprzez zamianę znaków napisu trzeciego na odpowiednich pozycjach z literami
napisu drugiego, kiedy rozpatrujemy znaki na pozycjach nieparzystych. Przykład:
Dane: ABCDEFGHIJ abcdefghij 0123456789.
Wynik: 0B2D4F6H8J a1c3e5g7i9 AbCdEfGhIj

Moje Wypociny:
(Na potrzeby szybszych testów celowo zmiejszyłem długość napisów)

public class Zad1 {

    static String getStringWithException() {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter new string:");
        String text = sc.nextLine();

        if (!text.matches("[A-Z]{4} [a-z]{4} [0-9]{4}")) {
            throw new IllegalStateException("String is not correct: " + text);
        }
        return text;
    }

    static String stringchanger(String txt) {

          if(txt == null){
              throw new IllegalArgumentException("txt is null");
          }

        int counter = 0;
        char[] array = txt.toCharArray();
        char[] txt3array = new char[txt.length()];
        char[] wyraz3 = Arrays.copyOfRange(array, 10, array.length);

        for (int i = 0; i < txt3array.length; i++) {

            if (counter == wyraz3.length) {
                txt3array[i] = ' ';
                counter = 0;
                i++;
            }

            txt3array[i] = wyraz3[counter];
            counter++;

        }

        for (int i = 0; i < txt3array.length; i++) {
            if (i < 4) {
                if (i % 2 == 0) {
                    txt3array[i] = wyraz3[i];
                } else {
                    txt3array[i] = array[i];
                }
            } else if (i == 4) {
                txt3array[i] = ' ';
            }
            if (i > 4 && i < 11) {
                if (i % 2 == 0) {
                    txt3array[i] = array[i];
                } else {

                }
            }
        }
        return new String(txt3array);
    }

    public static void main(String[] args) {
        System.out.println(stringchanger(getStringWithException()));

    }
}

Metoda StringChanger zamienia mi odpowiednio znaki w pierwszych 2 członach napisu. Trzeciego członu nawet nie robiłem bo sami widzicie jak to wygląda. Z pewnością da się to zrobić 10 razy bardziej elegancko. Jakieś pomysły ??
Z góry dzięki :)

edytowany 3x, ostatnio: manifestor, 2019-05-31 12:23
Popraw tytuł swojego wątku: Jak tytułować wątki na forum. - Patryk27 2019-05-31 12:16

Pozostało 580 znaków

2019-05-31 13:03
0

Na szybko:

package com.company;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {

    private static final int LENGTH = 10;
    private static final int PHRASES_COUNT = 3;
    private static final Pattern PATTERN =
        Pattern.compile("([A-Z]{" + LENGTH + "}) ([a-z]{" + LENGTH + "}) ([0-9]{" + LENGTH + "})");

    public static void main(String[] args) {
        System.out.println(process("ABCDEFGHIJ abcdefghij 0123456789"));
    }

    static String process(String input) {
        Matcher matcher = PATTERN.matcher(input);
        if (matcher.matches()) {
            char[][] phrases = IntStream.rangeClosed(1, PHRASES_COUNT)
                .mapToObj(i -> matcher.group(i).toCharArray())
                .toArray(char[][]::new);
            iterate(0).forEach(i -> swap(phrases[0], phrases[2], i));
            iterate(1).forEach(i -> swap(phrases[1], phrases[2], i));
            return Arrays.stream(phrases)
                .map(String::new)
                .collect(Collectors.joining(" "));
        }
        return input;
    }

    static IntStream iterate(int from) {
        return IntStream.iterate(from, i -> i + 2)
            .limit(LENGTH / 2);
    }

    static void swap(char[] first, char[] second, int index) {
        char temp = first[index];
        first[index] = second[index];
        second[index] = temp;
    }
}
Tutaj znów aż za ładnie. Kolekcji i strumieni jeszcze nie miałem. Ale dzięki :) - manifestor 2019-05-31 13:18

Pozostało 580 znaków

2019-05-31 13:07
0

Stringa możesz podzielić metodą String.split()
To może być coś takiego:

for (int i=0; i<length; ++i){
            if(i%2==0){
                swap(first, third, i);
            }
            else{
                swap(second, third, i);
            }
        }
private static void swap(char[] i, char[] j, int n)

Pozostało 580 znaków

2019-05-31 14:22
0

Jest też StringBuilder

    static void swapCharsInBuildersAtIndex(StringBuilder builder1, StringBuilder builder2, int index) {
        char char1 = builder1.charAt(index);
        builder1.setCharAt(index, builder2.charAt(index));
        builder2.setCharAt(index, char1);
    }

    static String stringchanger2(String txt) {
        String[] tokens = txt.split(" ");
        final int TOKEN_LENGTH = tokens[0].length();

        List<StringBuilder> stringBuilders = Arrays.stream(tokens)
                .map(StringBuilder::new)
                .collect(Collectors.toList());

        for (int i = 0; i < TOKEN_LENGTH; i++) {
            if (i % 2 == 0) {
                swapCharsInBuildersAtIndex(stringBuilders.get(0), stringBuilders.get(2), i);
            } else {
                swapCharsInBuildersAtIndex(stringBuilders.get(1), stringBuilders.get(2), i);
            }
        }

        return stringBuilders.stream().map(StringBuilder::toString).reduce((s1, s2) -> s1 + " " + s2).get();
        //czyli return stringBuilders.get(0) + " " + stringBuilders.get(1) + " " + stringBuilders.get(2);
    }
edytowany 1x, ostatnio: Potat0x, 2019-05-31 14:25

Pozostało 580 znaków

2019-05-31 18:56
0
RewAnd napisał(a):

Stringa możesz podzielić metodą String.split()
To może być coś takiego:

for (int i=0; i<length; ++i){
          if(i%2==0){
              swap(first, third, i);
          }
          else{
              swap(second, third, i);
          }
      }
private static void swap(char[] i, char[] j, int n)

Coś takiego??

public class Zad1 {

    static String getStringWithException() {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter new string:");
        String text = sc.nextLine();

        if (!text.matches("[A-Z]{4} [a-z]{4} [0-9]{4}")) {
            throw new IllegalStateException("String is not correct: " + text);
        }
        return text;
    }

    static String stringchanger(String txt) {

        if (txt == null) {
            throw new IllegalArgumentException("txt is null");
        }

        String[] stringArray = txt.split(" ");
        System.out.println(Arrays.toString(stringArray));

        char[] part1 = stringArray[0].toCharArray();
        char[] part2 = stringArray[1].toCharArray();
        char[] part3 = stringArray[2].toCharArray();

        for (int i = 0; i < part1.length; i++) {
            if (!(i % 2 == 0)) {
                swap(part1, part3, i);
            }
        }

        for (int i = 0; i < part2.length; i++) {
            if (i % 2 == 0) {
                swap(part2, part3, i);
            }
        }

        for (int i = 0; i < part3.length; i++) {
            if (i % 2 == 0) {
                swap(part3, part1, i);
            } else {
                swap(part3, part2, i);
            }
        }

        return convertCharArray(part1, part2, part3);
    }

    static String convertCharArray(char[] arr1, char[] arr2, char[] arrr3) {

        if(arr1 == null || arr2 == null || arrr3 == null){
            throw new IllegalArgumentException("array is null");
        }

        String string1 = new String(arr1);
        String string2 = new String(arr2);
        String string3 = new String(arrr3);

        return string1 + string2 + string3;
    }

    static void swap(char[] first, char[] digits, int index) {
        if(first == null || digits == null){
            throw new IllegalArgumentException(" array is null");
        }

        if(index < 0){
            throw new IllegalArgumentException("index is incorrect");
        }

        char[] copyDigits = Arrays.copyOf(digits, digits.length);
        first[index] = copyDigits[index];

    }

    public static void main(String[] args) {
        System.out.println(stringchanger("IKJU dgft 5623"));

    }
}
edytowany 1x, ostatnio: manifestor, 2019-05-31 19:00

Pozostało 580 znaków

2019-05-31 19:11

Te trzy pętle można zastąpić jedną, którą Ci napisałem :)

Pozostało 580 znaków

2019-05-31 20:02
0
RewAnd napisał(a):

Te trzy pętle można zastąpić jedną, którą Ci napisałem :)

Zmienione. Działa. Nie wiem jakim cudem czasami nie widzę tak oczywistych rzeczy grrr :(

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0