2011-02-11 5 views
6

:その後、私は、ユーザーが番号を入力してみましょうインデックスを使用して地図にアクセスしますか?私はこのマップを持っている

m.insert(pair<int, string>(10, "map1")); 
m.insert(pair<int, string>(11, "map2")); 
m.insert(pair<int, string>(12, "map3")); 
m.insert(pair<int, string>(13, "map4")); 
m.insert(pair<int, string>(14, "map5")); 

Please select: 
1. Map1 
2. Map2 
3. Map3 
4. Map4 
5. Map5 

は、私は値を取得しますどのように、ユーザは、3を入力した場合、言ってみましょう:12 ??

+0

要件を正しく取得しましたか?私はあなたが価値を知ってキーを欲しかったと思います。 – Jagannath

+0

ペアの整数があなたの値ならば、あなたのキーと値のペアは逆の順序になります。これは 'pair 'である必要があります。次に、ユーザが '3'を選択すると、' m [string( "map")+ string(itoa(selection))] 'のように取得できます。 – yasouser

+0

私は、メニューを表示するルーチンがコンテナを反復するので、メニューオプションは本当に(1つ以上の)インデックスになると考えました。答えは、それを表示するのと同じように、オプションが何であるかを識別するためにコンテナを反復することです。 – Steve314

答えて

3

std::mapは、要素の挿入順序を追跡しません。要素は挿入順ではなくソート順で格納されます。要素が挿入された順序を追跡する必要がある場合は、自分で行う必要があります。これを行う1つの方法は、例えば、std::vectorを使用して、順番に鍵を記憶する第2の容器を保持するであろう:

std::vector<int> insertion_order; 

m.insert(std::make_pair(10, "map1")); 
insertion_order.push_back(10); 

そして、要素挿入N番目のキーは、insertion_orderインデックスN - 1でありますシーケンス。ドキュメントから

+0

私はそれを取得しないでください。このように:map > ??それはあなたが意味することですか? –

+1

私の最初の提案は理想的ではありませんでした。この新しい提案を考えてみましょう。 –

0

が比較:比較クラス:キー型の2つの引数を取り、ブール値を返すクラス。式comp(a,b)compがこの比較クラスのオブジェクトであり、aとbがキー値である)は、aが厳密な弱い順序付け操作でbより前の位置に置かれる場合はtrueを返す。これは、関数呼び出し演算子を実装しているクラスでも、関数へのポインタでも構いません(例のコンストラクタ参照)。 デフォルトはless<Key>です。これは、より小さい演算子(a<b)を適用するのと同じ結果を返します。 マップオブジェクトはこの式を使用して、コンテナ内の要素の位置を決定します。マップコンテナ内のすべての要素は、この規則に従って常に順序付けられます。

したがって、マップクラスは要素の順序を配列として維持しません。インデックス演算子がある場合はではなく、はi番目の要素をマップに追加します。それは協調的なコレクションであり、挿入の時間によって注文を維持する必要がある場合、通常はそのタイプのデータ構造を使用しません。

4

現在の設定では、これを簡単に行う方法はありません。あなたは値としてMap3を持っていたものを探しているマップのすべての要素を反復しなければなりません。

mapは、一方向の関係を検索するために最適化されています。 map<K, V>を指定すると、KからVに簡単にマップできますが、それ以外の方法ではマップできません。その理由は、Vを値として保存できるため、一意的な逆数を保証するものではありません。つまり、このマップでは、

0 -> 0 
1 -> 0 
2 -> 1 

値0のキーは意味がありません。 0と1の2つのキーがあります。

ここには多くのオプションがあります。まず、mapを回り、代わりに文字列で整数ではなく文字列を整数に関連付けることができます。あなたのユースケースに基づいて、これは最初にやりたかったようです。

cout << m["Map3"] << endl; 

それとも、あなたが不足している値で何が起こるかについて心配していた場合、その後、あなたは

map<string, int>::iterator itr = m.find("Map3"); 
if (itr != m.end()) { 
    /* ... use itr to read the values ... */ 
} 
を書くことができます:あなたがいることをやった場合は、単に関連する値をルックアップするために、角括弧演算子を使用することができます

また、整数から文字列へのマップを実際に持たなければならず、各整数が一意の文字列とペアになっていることがわかっている場合(つまり、マップが双射性である場合)は、この双方向関係を符号化するBoost.Bimap。これにより、キーと値の間を行き来するのが非常に簡単になります。

希望すると便利です。

2

メニューの整数を保存するデータにマップします。検討してください:

struct data { 
    data(int n, const std::string& s) : s(s), n(n) { } 
    std::string s; 
    int n; 
}; 

// ... 
std::map<int,data> m; 
m.insert(make_pair(1, data(10, "Map1")); 
m.insert(make_pair(2, data(11, "Map2")); 
m.insert(make_pair(3, data(12, "Map3")); 

int n = m[3].n; // 12 
関連する問題