[解決済み] CやC++で文字列を定位置で反転させるにはどうしたらいいですか?
2022-04-15 21:54:09
質問
CまたはC++で、反転した文字列を保持するために別のバッファを必要とせずに文字列を反転するにはどうすればよいですか?
どのように解決するのですか?
標準的なアルゴリズムは、開始と終了のポインタを使い、それらが中央で出会うか交差するまで内側に歩くことである。 その都度、入れ替えを行う。
逆ASCII文字列、すなわち、すべての文字が1に収まる0終端の配列。
char
. (または他の非マルチバイト文字セット)。
void strrev(char *head)
{
if (!head) return;
char *tail = head;
while(*tail) ++tail; // find the 0 terminator, like head+strlen
--tail; // tail points to the last real char
// head still points to the first
for( ; head < tail; ++head, --tail) {
// walk pointers inwards until they meet or cross in the middle
char h = *head, t = *tail;
*head = t; // swapping as we go
*tail = h;
}
}
// test program that reverses its args
#include <stdio.h>
int main(int argc, char **argv)
{
do {
printf("%s ", argv[argc-1]);
strrev(argv[argc-1]);
printf("%s\n", argv[argc-1]);
} while(--argc);
return 0;
}
長さが既知の整数配列の場合も同じアルゴリズムが使えます。
tail = start + length - 1
終端探索ループの代わりに
(編集部注:この回答も、当初はこのシンプルなバージョンにXORスワップを使っていました。 今後、この人気のある質問を読む人のために修正しました。 XOR-swapは なかなか 推奨しない 読みにくく、コードのコンパイル効率が悪くなります。 ご覧の通りです。 ゴッドボルトコンパイラエクスプローラで xor-swapをgcc -O3でx86-64用にコンパイルした場合、asmのループ本体がどれだけ複雑になるか)。
よし、わかった、UTF-8文字を直そう...。
(これはXORスワップのことです。注意することは
を避けなければなりません。
は self とスワップします。
*p
と
*q
XORスワップは、2つの異なるロケーションを持ち、それぞれを一時的なストレージとして使用することに依存します)。
編集部注:SWPをtmp変数を使った安全なインライン関数に置き換えることができます。
#include <bits/types.h>
#include <stdio.h>
#define SWP(x,y) (x^=y, y^=x, x^=y)
void strrev(char *p)
{
char *q = p;
while(q && *q) ++q; /* find eos */
for(--q; p < q; ++p, --q) SWP(*p, *q);
}
void strrev_utf8(char *p)
{
char *q = p;
strrev(p); /* call base case */
/* Ok, now fix bass-ackwards UTF chars. */
while(q && *q) ++q; /* find eos */
while(p < --q)
switch( (*q & 0xF0) >> 4 ) {
case 0xF: /* U+010000-U+10FFFF: four bytes. */
SWP(*(q-0), *(q-3));
SWP(*(q-1), *(q-2));
q -= 3;
break;
case 0xE: /* U+000800-U+00FFFF: three bytes. */
SWP(*(q-0), *(q-2));
q -= 2;
break;
case 0xC: /* fall-through */
case 0xD: /* U+000080-U+0007FF: two bytes. */
SWP(*(q-0), *(q-1));
q--;
break;
}
}
int main(int argc, char **argv)
{
do {
printf("%s ", argv[argc-1]);
strrev_utf8(argv[argc-1]);
printf("%s\n", argv[argc-1]);
} while(--argc);
return 0;
}
- なぜかというと、そうなんです、入力がボロボロになると、これは元気よくその場の外にスワップしてくれるんです。
- UNICODEで荒らすときに便利なリンクです。 http://www.macchiato.com/unicode/chart/
- また、0x10000以上のUTF-8は未検証です(そのためのフォントは持っていないようですし、ヘキサエディタを使う忍耐力もありませんから)。
例
$ ./strrev Räksmörgås ░▒▓○◔◑◕●
░▒▓○◔◑◕● ●◕◑◔○▓▒░
Räksmörgås sågrömskäR
./strrev verrts/.
関連
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] バイトを文字列に変換する
-
[解決済み] Pythonで文字列の部分文字列を取得するにはどうすればよいですか?
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない