web-dev-qa-db-ja.com

`std :: set`はすべての場合に要素をソートしますか?

cplusplus.com 参照から、std::set要素を並べ替えます。

文字列を並べ替える必要がありますが、すべてのプラットフォームとコンパイラでうまく機能するかどうかはわかりません。主にGCC、MinGW、VC。

16
kravemir

その定義によりstd::setはソートされたコンテナです。標準の一部です。ソートしておくと、任意のコレクションではなく、そのセットを維持するのに役立ちます。

出典: http://www.sgi.com/tech/stl/set.html

26
Daniel A. White

実際には、std :: setとstd :: mapは実際にはソートされていません。これらのコンテナは両方とも 赤黒木 として実装されます。したがって、このような種類のコンテナーを反復処理すると、イテレーターは、そのコンテナーがソートされているように見えるようにツリーをウォークスルーします。最初に最も左のノードにアクセスし、次に最も左のノードの親にアクセスします。

13

はい、std::setは、要素の反復がソートされた順序で実行されるように要素を格納します(また、std::adjacent_findの呼び出しは、std::setが一意のアイテムも格納することを示します) 。

#include <algorithm>
#include <iterator>
#include <ios>
#include <iostream>
#include <set>
#include <string>

int main()
{
    auto const ss = std::set<std::string> { "foo", "bar", "test" };
    std::cout << std::boolalpha << std::is_sorted(begin(ss), end(ss)) << "\n";
    std::cout << std::boolalpha << (std::adjacent_find(begin(ss), end(ss)) == end(ss)) << "\n";
    std::copy(begin(ss), end(ss), std::ostream_iterator<std::string>(std::cout, "\n"));
}

実例

6
TemplateRex

C++ 11 N3337標準ドラフト23.2.4「連想コンテナ」:

1連想コンテナは、キーに基づいてデータを高速に取得します。ライブラリは、set、multiset、map、multimapの4つの基本的な種類の連想コンテナを提供します。

そして:

10連想コンテナのイテレータの基本的な特性は、キーの降順ではない順序でコンテナを反復することです。降順ではないのは、コンテナの構築に使用された比較によって定義されます。

そうです、順序は保証されています。 https://stackoverflow.com/a/11812871/895245 言及されているように、基本的にバランスの取れた検索ツリーの実装が必要です。

また、C++ 11とは対照的ですunordered_set、制限が少ないため、パフォーマンスが向上する可能性があります: 一体なぜunordered_setの代わりにsetを使用するのでしょうか? 例:ハッシュセットを使用します。