2008-10-21 6 views
1

Si j'ai la chaîne .....ZZ..ZZ..... ou .Z.1.Z.23Z.4.Z55,Un moyen facile de déplacer des caractères spécifiques dans une chaîne en C++?

est-il un moyen facile de déplacer tous Z caractères dans la chaîne un droit de l'espace de la position actuelle?

Certaines chaînes de test supplémentaires sont:

  • .Z
  • Z.
  • ZZ.
  • .ZZ
  • Z
  • ZZ
  • ZZZ

Je pense que quelques-unes des plus voté des réponses à cette question (y compris celui qui est actuellement acceptée) ne fonctionnent pas sur ces tests.

+0

Vous devez donner une meilleure spécification. Quand vous dites «passer à droite», voulez-vous dire échanger le «Z» et le personnage à sa droite? Déplacer et mettre un espace (ou quelque chose) à l'endroit où il était? Que faire si le 'Z' est le dernier caractère? Quelle est la sortie correcte pour vos chaînes de test? –

+0

Veuillez également donner la bonne réponse pour chacune des chaînes de test. Les énoncer simplement et que les solutions données ne fonctionnent pas n'est pas beaucoup d'aide. –

Répondre

5

Juste itérer le texte et les caractères échange:

int main() 
{ 
    char text[] = "...Z.Z.Z...", temp; 
    int text_len = strlen (text), i; 
    for (i = text_len - 1; i >= 0; i--) 
    { 
     if (text[i] == 'Z') 
     { 
       temp = text[i+1]; 
       text[i+1] = text[i]; 
       text[i] = temp; 
     } 
    } 
    printf ("%s\n", text); 
    return 0; 
} 

Produit:

[~]$ gcc zshift.c && ./a.out 
....Z.Z.Z.. 

Il y a beaucoup de discussions dans les commentaires sur une éventuelle erreur off-by-1 le code ci-dessus. Cependant, des tests/étapes simples suffisent à montrer que ce n'est pas le cas.

zshift "Z." -> ".Z" 
zshift ".Z" -> "." 
zshift "Z" -> "" 

Je pense que le comportement de « laisser tomber » Zs de fuite lors du passage à l'extrémité de la chaîne est sensible. Après tout, si vous déplacez les bits d'un nombre entier, les bits qui se retrouvent en dehors des limites de l'entier sont supprimés.

Si un autre comportement est souhaité - par exemple, déplacer uniquement dans la chaîne - la modification de l'algorithme est minime:

temp = text[i+1]; 
if (temp == 0) continue; 
text[i+1] = text[i]; 
text[i] = temp; 
+0

Je pensais qu'il a dit à droite pas à gauche :-) –

+0

@Martin: oh, oups, va changer –

+0

mais que faire si vous avez 2 Z l'un à côté de l'autre, ou 3 Z ou 4, etc et vous vouliez déplacer chacun d'entre eux ? – Tomek

0

fix légèrement à la réponse précédente (décalage à droite et prendre ' . 'signifie "peut se déplacer ici"):

char text[] = "...Z.Z.Z..."; 

    for (int i = strlen(text) - 2); i > 0; --i) { 
    if (text[i] == 'Z' && text[i + 1] == '.') { 
     text[i] = '.'; 
     text[i + 1] = 'Z'; 
    } 
    } 
+0

mais que se passe-t-il si vous avez 2 Z l'un à côté de l'autre, ou 3 Z ou 4, etc. et que vous vouliez déplacer chacun d'eux? – Tomek

+0

Je crois que le code ci-dessus devrait le faire. Il va décaler le plus à droite, puis le plus à droite, etc. E.g. commençant par: ZZ. Étapes aboutirait à: ZZ. Z.Z .ZZ –

2

En se basant sur le code précédemment affiché ici. La fonction obtient str et strlen, écrase str. Fonctionne également avec Z. ultérieure avenir pour l'amélioration de la vitesse avec Z. ultérieure

void move_z_right (char* str, int strlen) { 
    for (unsigned int i = 0; i < strlen - 1; ++i) 
    { 
     if (str[i] == 'Z') 
     { 
      unsigned int j = i+1; 
      while (str[j] == 'Z' && j < strlen - 1) ++j; 
      if (j == strlen) break; // we are at the end, done 
      char tmp = str[j]; 
      str[j] = str[i]; 
      str[i] = tmp; 
      i = j; // continue after new Z next run 
     } 
    } 
} 

Notez que la solution de John Millikin est plus agréable à lire et aussi correct.

+0

Je pense que c'est la première réponse de travail que j'ai vue –

Questions connexes