2017-09-27 5 views
2

Mon but est d'obtenir le caractère après l'ajout du modèle donné dans la liste de tableaux. Mon problème est qu'avec ce code, j'ai une erreur avec i. Il dépasse la longueur du texte.Je souhaite ajouter le caractère après chaque occurrence d'un modèle dans une chaîne à une liste de caractères

public static ArrayList<Character> getCharsThatFollowPattern (String text, String pattern) 
    { 
    ArrayList<Character> charAfterPattern = new ArrayList<Character>(); 
    int patternLength = pattern.length(); 
    int i = 0; 
    while (i < text.length()) 
    { 
     charAfterPattern.add(text.charAt(text.indexOf(pattern, i) + patternLength)); 
     i = i + text.indexOf(pattern, i) + patternLength; 
    } 
    return charAfterPattern; 
} 
+1

Quelle est l'erreur que vous obtenez? BTW, si vous passez votre code dans votre débogueur, vous le comprendrez probablement vous-même. – dave

+2

Qu'essayez-vous vraiment de faire? Il est très courant de traiter 'ArrayList ' quand un simple 'String' (ou au pire un' StringBuilder') fait essentiellement la même chose. – Bohemian

+0

Je reçois l'index IndexOutOfBoundsException: string hors de portée: 7 –

Répondre

0

Je peux voir trois problèmes principaux avec votre code.

Les deux premiers sont liés à la façon dont indexOf() fonctionne.

  • Il renvoie -1 lorsque le motif est introuvable. Vous n'autorisez pas ce cas et par conséquent, traitez deux parties de la chaîne deux fois.
  • Renvoie l'index relatif au et commence de la chaîne, même si vous effectuez une recherche à partir d'un endroit autre que le début. Par conséquent, vous ne devriez pas faire i = i + text.indexOf(..., mais plutôt i = text.indexOf(....

Le troisième problème est que vous ne gérez pas correctement le cas où le motif est à la fin du texte, à savoir. il n'y a pas de caractère suivant.

Voici ma solution grossière basée sur le vôtre:

public static List<Character> getCharsThatFollowPattern (String text, String pattern) 
{ 
    List<Character> charAfterPattern = new ArrayList<Character>(); 
    int patternLength = pattern.length(); 
    int i = 0; 
    while (i < text.length()) 
    { 
     int index; 
     if ((index = text.indexOf(pattern, i)) < 0) // Check pattern is present 
      break; 
     i = index + patternLength; 
     if (i < text.length()) // Check there is a next character 
     { 
      charAfterPattern.add(text.charAt(i)); 
     } 
    } 
    return charAfterPattern; 
} 

essais de base:

("abc", "ab")  => [ 'c' ] 
("abcabdabe", "ab") => [ 'c', 'd', 'e' ] 
("abcabdab", "ab") => [ 'c', 'd' ] 
("ababdab", "ab") => [ 'a', 'd' ] 
0

Voici une solution simple en utilisant un type de retour plus approprié de String:

public static String getCharsThatFollowPattern(String text, String pattern) { 
    return text.replaceAll(".*?" + pattern + "(.)(.(?!" + pattern + "))*", "$1"); 
} 

Si vous désespérément, absolument devez avoir un List<Character>, tourner le ci-dessus en à Type:

public static List<Character> getCharsThatFollowPattern(String text, String pattern) { 
    return text.replaceAll(".*?" + pattern + "(.)(.(?!" + pattern + "))*", "$1") 
     .chars().mapToObj(i -> (char) i).collect(Collectors.toList()); 
} 

Notez également que vous devez toujours utiliser le type le plus abstrait pour les API de la méthode, à savoir List<Character> pas ArrayList<Character>. Voir Liskov substitution principle.

+0

Avec vos deux méthodes et mon exemple original, il ne renvoie que [' b '] au lieu de [' b ',' b ']. C'est pour l'école donc ça doit être un ArrayList –

+0

Désolé pas mon exemple original. Le test dont j'ai besoin pour passer est "abababa", "aba" et il retourne ['b', 'b'] –

+0

@evan es-tu sûr qu'il devrait retourner ['b']? En d'autres termes, est-il nécessaire que vous * réutilisiez * l'entrée lors de la correspondance? – Bohemian