web-dev-qa-db-ja.com

std :: stringの前に追加

std::stringを付加する最も効率的な方法は何ですか?そうすることは関数全体を書き出す価値がありますか、それとも1-2行しかかからないでしょうか? std::string::Push_frontに関連するものは見当たりません。

48
zeboidlund

実際には、存在しないstd::string::Push_frontと同様の関数があります。以下の例を参照してください。


std :: string :: insertのドキュメント

#include <iostream>
#include <string>

int
main (int argc, char *argv[])
{
  std::string s1 (" world");
  std::string s2 ("Ello");

  s1.insert (0,     s2); // insert the contents of s2 at offset 0 in s1
  s1.insert (0, 1, 'h'); // insert one (1) 'h'        at offset 0 in s1

  std::cout << s1 << std::endl;
}

出力:

hello world

文字列の前にデータを追加すると、再割り当てと既存データのコピー/移動の両方が必要になる場合があるため、std::string::reserveを使用して再割り当て部分を削除することでパフォーマンスを向上させることができます.

データのコピー/移動は、大きなバッファを割り当てて最初のコンテンツをこのメモリバッファの中央に配置するstd::stringのように動作する独自のカスタムクラスを定義しない限り、非常に避けられません。

その後、バッファが十分な大きさである場合、データの再割り当てと移動を行わずにデータを追加および追加できます。ただし、sourceからdestinationへのコピーは、当然ながら必要です。


prependデータを頻繁にappend適切な代替方法は、文字列を逆方向に保存し、必要に応じて逆にすることです(それがよりまれな場合)。

70
myString.insert(0, otherString);

標準テンプレートライブラリの作成者に効率を心配させてください。ホイールを再プログラミングするのではなく、すべての時間を活用します。

この方法は、これらの両方を行います。

使用しているSTL実装が熟考されている限り、効率的なコードが得られます。ひどく書かれたSTLを使用している場合、とにかく大きな問題があります:)

6
matiu

std::string::appendを使用している場合、以下が同等であることを理解する必要があります。

std::string lhs1 = "hello ";
std::string lh2 = "hello ";
std::string rhs = "world!";

lhs1.append(rhs);
lhs2 += rhs; // equivalent to above
// Also the same:
// lhs2 = lhs + rhs;

同様に、「prepend」は次と同等です。

std::string result = "world";
result = "hello " + result;
// If prepend existed, this would be equivalent to
// result.prepend("hello");

ただし、上記を行うのはかなり非効率的であることに注意してください。

5
Mike Bailey

オーバーロードされたstring operator+ (char lhs, const string& rhs);があるので、ただyour_string 'a' + your_string 模倣します Push_front

これはインプレースではありませんが、新しい文字列を作成するため、効率的であるとは思わないでください。 (おそらく)より効率的なソリューションを得るには、resizeを使用してスペースを収集し、std::copy_backwardは、文字列全体を1つずつ戻し、新しい文字を先頭に挿入します。

3