2012-03-24 16 views
3

つまり、unordered_mapまたはunordered_setの2つを入力すると、同じ内容と同じハッシュ関数を持つオブジェクトは、繰り返し処理されて同じキー/値ペアのシーケンスが得られますか?同じ2つのunordered_mapの順序は同じですか?

もしそうなら、これが保持する条件は何ですか(同じハッシュ関数、同じキー、必ずしも同じ値ではない)。

+1

あなたが考えているハッシュ関数は、実際に使用される最終的なハッシュ関数ではありません。バケットのサイズは動的に変更でき、実際のハッシュ関数はあなたのハッシュ関数から導出されます(おそらく、いくつかのモジュラ - 算術的な方法で)。 –

答えて

5

号に共通である必要は同じハッシュを持つオブジェクトは、任意の特定の順序に配置すること、例えば、存在しません。実際には、一般に、順序付けされていないマップでは、これがアクセスできる唯一の情報はハッシュ値なので、これを行うことは不可能です。

+1

同じキーを持つアイテムを同じサイズの同じハッシュ関数を持つ同じ順序でコンテナの同じサイズに追加した場合(つまり、「予約」などで何かを実行していない場合)、何が異なる順序で並べ替えることができますか? –

+0

ええ、そうです。それが私が求めていることです。実際には指定されていませんが、実際には指定されていますか? :) – pms

+3

@SethCarnegie:まず、OPは彼らが同じ順序で追加されるとは言っていませんでした。第二に、何でもそれらを別々に注文することができます。必要に応じて実装をランダムに並べ替えたり、最も頻繁にアクセスするオブジェクトを最初にハッシュチェーンに配置するように並べ替えることさえできます。 –

3

この場合の動作は未定義です。したがって、ある状況では、シーケンスは同じであり、異なる場合もあります。あなたは何でも確信することはできません。あなたが言及したタイプは、という名称で無作為にと命名されています。それらを順序付けられたものとして使用することは非常に非常に悪く、非常に危険なスタイルです。

コンパイラは、使用したいと考える特別な方法で動作します。しかし、あなたは確信することはできません。あなたは確信してはいけません!あなたは、どのような条件がコンパイラのそのような動作を引き起こしているのか分かりません。コンパイラのバージョンを変更しても、必要な動作が変わることは決してありません。

他の言語では禁止されているものは、C/C++では指定されていません。しかし、あなたはそれも禁じられているべきです。

ルックc-faq about the problem of undefined behaviorこの概念は、すべてのC/C++

+0

ええ..しかし、私は[ここ](http://stackoverflow.com/questions/3176621/c-is-the-unordered-map-really-unordered)読むことができますそれは可能であるようです... – pms

+3

起こる可能性があります。しかし、そうはならない可能性があります。 C/C++では、単に他の言語では禁止されているものは指定されていません。しかし、あなたはそれも禁じられているべきです。 – Gangnus

+1

@pms:「順序付けられていない」とは、「信頼できない順序で」ということです。これは、* C++仕様*が注文を定義しないことを意味します。あなたの 'std :: unordered_ * 'の実装は、確かに一定した順序を持つかもしれません。しかし、仕様は*これを強制するものではありません。一方、 'std :: map'では特定の順序を強制します。したがって、あなたのコードを移植可能にしたい場合は、注文に依存することはできません。 –

2

さて最初のIはMSDN引用します:

制御シーケンスの要素の実際の順序は、ハッシュ関数、比較機能、挿入のため、最大負荷率、および現在の数に依存

バケツの一般的に、制御された順序で要素の順序を予測することはできません。ただし、同等の順序付けを持つ要素のサブセットは、制御された順序で隣接していることが常に保証されます。

上記の引用はunordered_mapunordered_setのための同じで、名前は順序が指定されていない暗示するように、しかし、彼らは同等のキーが隣接していることを言及します。

+1

私はそれがMSの実装のためだけだと思いますか?それとも標準の要件ですか?実装では、衝突のために線形プロービングを使用するように強制されます(または、間接的な動的配列の各要素を格納する)。 –

+1

@SethCarnegie:それは必須と思われます。私はそれについてのディスカッションを見つけました[ここ](https://groups.google.com/group/comp.std.c++/tree/browse_frm/month/2006-11/19fc7cb847e9127b?rnum = 1&_done =/group/comp.std.c%2B%2B/browse_frm/month/2006-11?&hl = pt)(チェックポスト6) –

0

ご注文の保証が必要な場合は、でなく、のデータ構造です。実際、主に反復処理を行う場合は、unordered_map/setもデータ構造体ではありません。

反復の場合、あるノードから次のノードへのgonigはアルゴリズム的に複雑ではないため、std::mapはより良いデータ構造になります。 std::mapのオブジェクトの反復順序は、仕様によって保証されているです(実際には構造自体の定義プロパティです)。 (これはすべて、同じ比較演算子を使用していることを前提としています)。 std::mapにハッシングはありません。

ここで間違ったツリーを吠えているように聞こえます。 unordered_mapは一般的にO(1)ルックアップなどの利点を利用するべきであり、オブジェクトのリストを格納してそれらを反復するべきではありません。決定的な反復順序を取得しようとしている場合は、の間違いなくを使用すべきではありません。

+0

もちろん、私はそれを反復するだけではありません:) – pms

+0

もちろんです。しかし、それがコードのパフォーマンスに影響されやすい部分であれば、あなたが行う唯一のことでもあります。 –

+0

私はハッシュテーブルを理由のために使いますが、あなたはそのポイントを逃してしまいます。 – pms

関連する問題