Einfache Möglichkeit, bestimmte Zeichen in einer Zeichenfolge in C ++ zu verschieben?
Frage
Wenn ich die Zeichenfolge .....ZZ..ZZ.....
oder .Z.1.Z.23Z.4.Z55
,
Gibt es eine einfache Möglichkeit, alle Z
characters 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.
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';
}
}