C ++で文字列内の特定の文字をシフトする簡単な方法は?
質問
文字列 ..... ZZ..ZZ .....
または .Z.1.Z.23Z.4.Z55
がある場合、
文字列内のすべての Z
文字を現在の位置の1スペース右にシフトする簡単な方法はありますか?
追加のテスト文字列は次のとおりです。
-
.Z
-
Z。
-
ZZ。
-
.ZZ
-
Z
-
ZZ
-
ZZZ
この質問に対する上位投票の回答のいくつか(現在受け入れられているものを含む)は、これらのテストでは機能しません。
解決
テキストを繰り返し、文字を交換します:
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;
}
プロデュース:
[~]$ gcc zshift.c && ./a.out
....Z.Z.Z..
上記のコードで考えられるoff-by-1エラーに関するコメントには、多くの議論があります。ただし、そうではないことを示すには、簡単なテスト/ステップスルーで十分です。
zshift "Z." -> ".Z"
zshift ".Z" -> "."
zshift "Z" -> ""
「ドロップ」の動作は文字列の末尾からシフトアウトするときのZの末尾が適切です。結局、整数のビットをシフトすると、整数の境界の外側にあるビットはドロップされます。
別の動作が必要な場合(たとえば、文字列内でのみシフトする場合)、アルゴリズムへの変更は最小限です。
temp = text[i+1];
if (temp == 0) continue;
text[i+1] = text[i];
text[i] = temp;
他のヒント
以前に投稿されたコードの構築はこちら。関数はstrとstrlenを取得し、strを上書きします。後続のZでも機能します。後続のZで速度を改善するために前進します。
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
}
}
}
John Millikinのソリューションは読みやすく、修正にも優れていることに注意してください。
前の回答のわずかな修正(右にシフトし、「。」が「ここに移動できる」ことを意味すると仮定):
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';
}
}
所属していません StackOverflow