Einfache Möglichkeit, bestimmte Zeichen in einer Zeichenfolge in C ++ zu verschieben?

StackOverflow https://stackoverflow.com/questions/220832

  •  03-07-2019
  •  | 
  •  

Frage

Wenn ich die Zeichenfolge .....ZZ..ZZ..... oder .Z.1.Z.23Z.4.Z55,

Gibt es eine einfache Möglichkeit, alle Zcharacters in der Zeichenfolge ein Raum rechts von der aktuellen Position zu verschieben?

Einige zusätzliche Test-Strings sind:

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

Ich denke, einige der höheren gestimmten Antworten auf diese Frage (einschließlich dem zur Zeit eines akzeptierten) auf diesen Tests nicht funktionieren.

War es hilfreich?

Lösung

Just durchlaufen den Text und Swap-Zeichen:

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;
}

Erzeugt:

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

Es gibt viele Diskussionen in den Kommentaren über einen möglichen off-by-1 Fehler in dem obigen Code. Allerdings einfaches Testen / Schreiten durch genug ist, um zu zeigen, dass dies nicht der Fall ist.

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

Ich denke, das Verhalten von „dropping“ Zs Hinter, wenn das Ende der Strings Verschiebung weg ist sinnvoll. Nach allem, wenn Sie die Bits eines ganzzahligen verschieben, Bits, die außerhalb der Grenzen der ganzen Zahl am Ende werden gelöscht.

Wenn ein anderes Verhalten gewünscht wird - zum Beispiel Verschiebung nur innerhalb der Zeichenfolge - die Änderung des Algorithmus ist minimal:

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

Andere Tipps

Aufbauend auf bereits hier gepostet Code. Funktion bekommt str und strlen, überschreibt str. Funktioniert auch mit anschließendem Z. vorwärts für Geschwindigkeitsverbesserung mit anschließenden Z gehen.

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
        }
    }
}

Beachten Sie, dass John Millikin Lösung ist schöner zu lesen und auch zu korrigieren.

Leichte fix auf die vorherige Antwort (Verschiebung nach rechts und übernehmen bedeutet ‚kann hier bewegen‘ ‚‘):

  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';
    }
  }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top