3
votes

Fractionner une chaîne à chaque 4ème caractère?

J'ai une chaîne que je dois diviser en sous-chaînes de longueur égale si possible. J'ai trouvé cette solution qui ne fonctionnera que si la longueur de la chaîne est un multiple de 4.

[a, bcde, fghi, jklm]

Cela produira:

[abcd, efgh, ijkl, m]

Quoi j'ai besoin est de diviser "de la fin de la chaîne". Le résultat souhaité doit ressembler à:

String   myString = "abcdefghijklm";
String[] split = myString.split("(?<=\\G....)");

Comment puis-je y parvenir?


3 commentaires

Copie possible de Fractionnement d'une chaîne à chaque n-ième caractère


@Ruslan Ce n'est pas une copie de la question liée. Veuillez regarder ma sortie souhaitée.


Cela devrait être fait sans regex dans une simple boucle.


3 Réponses :


7
votes

Cela devrait le faire:

String[] split = myString.split("(?=(....)+$)");
// or
String[] split = myString.split("(?=(.{4})+$)");

Ce qu'il fait est ceci: diviser sur la chaîne vide uniquement si cette chaîne vide a un multiple de 4 caractères devant elle jusqu'à la fin de -input est atteint.

Bien sûr, cela a un mauvais runtime (O (n ^ 2)). Vous pouvez obtenir un algorithme de temps d'exécution linéaire en le divisant simplement vous-même.

Comme mentionné par @anubhava:

(?! ^) (? = (?:. {4}) + $) pour éviter les résultats vides si la longueur de la chaîne est en multiples de 4


4 commentaires

A tenté. Rend [a, bcde, fghi, jklm] comme demandé.


Merci beaucoup. Travaux.


(?! ^) (? = (?:. {4}) + $) pour éviter un résultat vide si la longueur de la chaîne est en multiples de 4


Merci à tous pour les améliorations et les explications.



1
votes

Pas besoin d'utiliser une expression régulière. Au lieu de cela, vous pouvez créer récursivement une liste de chaînes d'en-tête et renvoyer la queue.

import java.util.*;

public class StringChunker {
    public static void main(String[] args) {
        String str = "abcdefghijklm";

        System.out.println(Arrays.toString(chunk(str, 4)));        // [abcd, efgh, ijkl, m]
        System.out.println(Arrays.toString(chunk(str, 4, true)));  // [a, bcde, fghi, jklm]
    }

    public static String[] chunk(String str, int size) throws IllegalArgumentException {
        return chunk(str, size, false);
    }

    public static String[] chunk(String str, int size, boolean reverse) throws IllegalArgumentException {
        return chunk(str, size, reverse, new ArrayList<String>());
    }

    private static String[] chunk(String str, int size, boolean reverse, List<String> chunks) throws IllegalArgumentException {
        if (size < 1) {
            throw new IllegalArgumentException("size must be greater than 0");
        }
        if (str.length() < size) {
            if (reverse) {
                chunks.add(0, str); // Reverse adds to the front of the list
            } else {
                chunks.add(str); // Add to the end of the list
            }
            return chunks.toArray(new String[chunks.size()]); // Convert to an array
        } else {
            String head, tail;
            if (reverse) {
                head = str.substring(str.length() - size, str.length());
                tail = str.substring(0, str.length() - size);
                chunks.add(0, head);
            } else {
                head = str.substring(0, size);
                tail = str.substring(size);
                chunks.add(head);
            }
            return chunk(tail, size, reverse, chunks);
        }
    }
}


0 commentaires

3
votes

Les expressions régulières ne sont vraiment pas nécessaires pour cela. Je ne pense pas non plus que ce soit un bon problème pour la récursivité. Voici une solution O (n).

public static String[] splitIt(String input, int splitLength){

    int inputLength = input.length();
    ArrayList<String> arrayList = new ArrayList<>();

    int i = inputLength;
    while(i > 0){
        int beginIndex = i - splitLength > 0 ? i - splitLength : 0;
        arrayList.add(0, input.substring(beginIndex, i));
        i -= splitLength;
    }


    return arrayList.toArray(new String[0]);
}


0 commentaires