手元にある制約 (基本的にリストを逆にたどるのに行き詰まっている) を考えると、文字列も逆に構築し、すべての文字が追加されたら、文字列を逆にするのがおそらく最善です。
現在行っている方法では、二次的な複雑さが得られます。別の文字を挿入し、その文字を文字列に入れるたびに、既存のすべての文字を新しい文字列にコピーするため、各挿入は線形であり、N 回の挿入です。はおおよそ O(N 2 ) です。[注: 実際には、コードを読み間違えていました -- 悪いですが、それほど悪くはありません] 現在のところ、すべての文字が少なくとも 2 回コピーされると予想できます。1 回はスタックに、もう 1 回はスタックにコピーされます。宛先文字列。メモリ帯域幅の観点から考えると、おそらく非効率性が最も明白です。最低限、各呼び出しでは、ポインターを読み取り、現在の文字をスタックに書き込み、戻りアドレスを書き込む必要があります。これらはすべて、リンクされたリストから宛先文字列に 1 バイトをコピーするために必要です。64 ビットの実装を想定すると、ポインターの読み取りと書き込み (およびその他のオーバーヘッド) と実際に必要なデータのコピーの比率は 18:1 程度になります。
文字列を逆方向に作成してから逆方向に作成すると、文字列の末尾に新しい文字が追加されます。次に、追加するすべてのキャラクターに対して1回ではなく、1回だけ余分な移動をすべて行います。
を使用している場合std::vector<char>は、文字列の末尾に文字を追加すると、一定の複雑さが償却されると断言できます。(思い出すと) 複雑さの保証は得std::stringられませんが、1 文字をコピーするためだけに再帰呼び出しと同じくらいひどいものにするには、驚くほどひどい実装が必要になるでしょう。
別の可能性は、 のstd::deque<char>代わりにを使用することstringです。deque を使用すると、スペースを空けるために他のすべての文字を移動することなく、先頭に文字を挿入できます。これには 2 つの欠点があります。結果は (通常) メモリの連続したブロックではなく、通常は余分なレベルの間接化が発生するため、構築後のデータへのアクセスはわずかに遅くなります。