35

これは本当に私自身の興味のための質問であり、ドキュメントでは判断できませんでした。

http://www.cplusplus.com/reference/string/string/で、追加が複雑であることがわかります。

「特定されていませんが、通常、新しい文字列の長さは直線的です。」

push_back() には複雑さがあります。

「特定されていません。一般的に償却定数ですが、新しい文字列の長さは最大で線形です。」

おもちゃの例として、「foo」という文字を文字列に追加したいとします。だろう

myString.push_back('f');
myString.push_back('o');
myString.push_back('o');

myString.append("foo");

まったく同じことになるの?それとも違いはありますか?push_back は呼び出しごとにメモリを確保する必要があるかもしれませんが、コンパイラは文字列を指定された文字数に拡張するために必要なメモリ量を知っているため、append がより効率的であると考えるかもしれません。

4

4 に答える 4

46

C++03 (「cplusplus.com」のドキュメントのほとんどが書かれている) では、ライブラリの実装者が文字列のコピー オン ライトまたは「ロープ スタイル」の内部表現を行うことが許可されていたため、複雑さは特定されていませんでした。たとえば、COW 実装では、文字が変更され、共有が行われている場合、文字列全体をコピーする必要がある場合があります。

C++11 では、COW とロープの実装は禁止されています。最後に文字列に追加するために、追加される文字ごとに一定の償却時間、または追加される文字数の線形償却時間を期待する必要があります。実装者はまだ文字列を使って比較的クレイジーなことをするかもしれませんが (たとえば と比較してstd::vector)、ほとんどの実装は「小さな文字列の最適化」などに限定されます。

と を比較するpush_backappendpush_back潜在的に有用な長さ情報が基になる実装から奪われます。この情報は、スペースを事前に割り当てるために使用される可能性があります。一方、append実装ではその長さを見つけるために入力を 2 回ウォークスルーする必要があるため、パフォーマンスの向上または低下は、追加を試みる前の文字列の長さなど、多くの未知の要因に依存します。そうは言っても、その差はおそらく非常に非常に非常に小さいです。これをappend使用してください-はるかに読みやすいです。

于 2013-02-26T05:46:53.920 に答える
4

ここにもう 1 つ意見を追加します。

個人的にはpush_back()、別の文字列から1文字ずつ追加する場合に使用した方が良いと思います。例えば:

string FilterAlpha(const string& s) {
  string new_s;
  for (auto& it: s) {
    if (isalpha(it)) new_s.push_back(it);
  }
  return new_s;
}

ここで使用する場合は、読みにくい に置き換えappend()ます。push_back(it)append(1,it)

于 2014-08-30T01:24:42.253 に答える
0

append()はい、あなたが与えた理由により、パフォーマンスが向上することも期待できます。また、文字列を追加する必要がある状況では、 append()(or operator+=) を使用することをお勧めします (特に、コードがはるかに読みやすいため)。

しかし、標準で指定されているのは、操作の複雑さです。最終的append()には、追加される文字列の各文字 (および再割り当てが発生した場合はすべての文字が可能) をコピーする必要があるためです (これは、memcpyまたは類似の文字列が使用されている場合でも当てはまります)。

于 2013-02-26T05:45:28.583 に答える