Verificando se uma seqüência de caracteres é uma sequência de caracteres repetida
1. Introdução
Neste tutorial, mostraremos como podemos verificar em Java se aString é uma sequência de substrings repetidas.
2. O problema
Antes de continuarmos com a implementação, vamos definir algumas condições. Primeiro, vamos supor que nossoString tem pelo menos dois caracteres. Em segundo lugar, há pelo menos uma repetição de uma substring.
Isso é melhor ilustrado com alguns exemplos, verificando algumas substrings repetidas:
"aa"
"ababab"
"barrybarrybarry"
E alguns não repetidos:
"aba"
"cbacbac"
"carlosxcarlosy"
Mostraremos agora algumas soluções para o problema.
3. Uma solução ingênua
Vamos implementar a primeira solução.
O processo é bastante simples: vamos verificar o comprimento deString e eliminar o caractere únicoStrings logo no início.
Então,since the length of a substring can’t be larger than a half of the string’s length, iremos iterar pela metade deStringe criar a substring em cada iteração anexando o próximo caractere à substring anterior.
Em seguida, removeremos essas substrings doString original e verificaremos se o comprimento do "removido" é zero. Isso significaria que é feito apenas de suas substrings:
public static boolean containsOnlySubstrings(String string) {
if (string.length() < 2) {
return false;
}
StringBuilder substr = new StringBuilder();
for (int i = 0; i < string.length() / 2; i++) {
substr.append(string.charAt(i));
String clearedFromSubstrings = string.replaceAll(substr.toString(), "");
if (clearedFromSubstrings.length() == 0) {
return true;
}
}
return false;
}
Vamos criar algunsStrings para testar nosso método:
String validString = "aa";
String validStringTwo = "ababab";
String validStringThree = "exampleexample";
String invalidString = "aca";
String invalidStringTwo = "ababa";
String invalidStringThree = "examplenonrepeatedexample";
E, finalmente, podemos verificar facilmente sua validade:
assertTrue(containsOnlySubstrings(validString));
assertTrue(containsOnlySubstrings(validStringTwo));
assertTrue(containsOnlySubstrings(validStringThree));
assertFalse(containsOnlySubstrings(invalidString));
assertFalse(containsOnlySubstrings(invalidStringTwo));
assertFalse(containsOnlySubstrings(invalidStringThree));
Embora essa solução funcione,it’s not very efficient, pois iteramos pela metade deStringe usamos o métodoreplaceAll() em cada iteração.
Obviamente, ele vem com o custo referente ao desempenho. Ele será executado no tempoO(n^2).
4. A solução eficiente
Agora, vamos ilustrar outra abordagem.
Ou seja, devemos aproveitar o fato de quea String is made of the repeated substrings if and only if it’s a nontrivial rotation of itself.
A rotação aqui significa que removemos alguns caracteres do início de Stringe os colocamos no final. Por exemplo, “eldungba” é a rotação de “exemplo”. Se girarmos aString e obtermos o original, podemos aplicar essa rotação repetidamente e obterString consistindo de substrings repetidas.
Em seguida, precisamos verificar se esse é o caso do nosso exemplo. Para fazer isso, vamos fazer uso do teorema que diz que seString A and String B have the same length, then we can say that A is a rotation of B if and only if A is a substring of BB. Se seguirmos o exemplo do parágrafo anterior, podemos confirmar este teorema:baeldungbaeldung.
Como sabemos que nossoString A sempre será uma substring de AA, então só precisamos verificar seString A é uma substring de AA excluindo o primeiro caractere:
public static boolean containsOnlySubstringsEfficient(String string) {
return ((string + string).indexOf(string, 1) != string.length());
}
Podemos testar esse método da mesma maneira que o anterior. Desta vez, temosO(n) complexidade de tempo.
Podemos encontrar alguns teoremas úteis sobre o tópico emString analysis research.
5. Conclusão
Neste artigo, ilustramos duas maneiras de verificar se aString consiste apenas em suas substrings em Java.
Todos os exemplos de código usados no artigo estão disponíveisover on GitHub.