mapの入れ子

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
usagi500

mapの入れ子

#1

投稿記事 by usagi500 » 10年前

はじめまして。

map<int, map<string, map<int, int> > > data;

data[100]["testA"][107] = 200; // データの登録
data[300]["testB"][105] = 100; // データの登録

上記の登録をした場合、
 secondPool[200]["test"][107]
のデータが登録されているかチェックするには、
どうしたら良いのでしょうか?

よろしくお願いします。

Blue

Re: mapの入れ子

#2

投稿記事 by Blue » 10年前

こんな感じ?

コード:

bool bFindData = false;

map<int, map<string, map<int, int> > >::const_iterator it1 = data.find(100);
if (it1 != data.end())
{
	map<string, map<int, int> >::const_iterator it2 = it1->second.find("testA");
	if (it2 != it1->second.end()) {
		bFindData = it2->second.count(107);
	}
}
常に右にくるキーには複数のデータが付くのであれば、mapの入れ子として使ったほうがよいですが、
3つの要素で一つの値ということであるならば、入れ子にしないほうがいいかも。

Blue

Re: mapの入れ子

#3

投稿記事 by Blue » 10年前

コード:

bFindData = it2->second.count(107);

コード:

bFindData = it2->second.count(107) > 0;
でした。

アバター
Ketty
記事: 103
登録日時: 11年前

Re: mapの入れ子

#4

投稿記事 by Ketty » 10年前

自分ならこう書きます(^^)

コード:

// 調べたいキー
const int		key1 = 200 ;
const string	key2 = "test" ;
const int		key3 = 107 ;

// キーに該当するやつがあったらtrueを返します
if( data.count( key1 ) > 0 &&				// key1だけで調べてみて…
	data[key1].count( key2 ) > 0 &&			// あったら、key1とkey2で調べてみて…
	data[key1][key2].count( key3 ) > 0 )	// あったら、key1とkey2とkey3で調べてみる
{
	return true ; // あったよ
}
else
{
	return false ; // なかったよ
}

usagi500

Re: mapの入れ子

#5

投稿記事 by usagi500 » 10年前

ありがとうございます。
動きました。

 >3つの要素で一つの値ということであるならば、入れ子にしないほうがいいかも。

代入する値はダミーで、
3つのキー(1セット)が存在するか確認したかったのですが、
良くない方法ですか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: mapの入れ子

#6

投稿記事 by みけCAT » 10年前

言語が指定されていないようですが、以下C++と仮定して回答します。
usagi500 さんが書きました:代入する値はダミーで、
3つのキー(1セット)が存在するか確認したかったのですが、
良くない方法ですか?
存在するか確認するだけならstd::mapよりstd::setの方がいいと思います。
また、入れ子にはせずに、「3つのキーを格納する構造体(クラス)を定義し、<演算子をオーバーロードする」か、
「std::pairを組み合わせて3つのキーを格納できる型を作る」を行い、
その構造体又は型をstd::setのキーにした方がいいと思います。
前者の構造体を作る方を推奨します。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

zeek

Re: mapの入れ子

#7

投稿記事 by zeek » 10年前

> 「std::pairを組み合わせて3つのキーを格納できる型を作る」を行い
C++11 であれば std::tuple が使えますね。

usagi
記事: 9
登録日時: 10年前

Re: mapの入れ子

#8

投稿記事 by usagi » 10年前

言語は、C++ (RedHat)になります。

3つのキー(1セット)の追加、消去が容易、
かつ、とても高速性が求められています。

となると、どの方法が良いのでしょうか?

具体的なコードで教えていただければ助かります。
(どう書いて良いのかわからなくて...)

よろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: mapの入れ子

#9

投稿記事 by みけCAT » 10年前

usagi さんが書きました:言語は、C++ (RedHat)になります。

3つのキー(1セット)の追加、消去が容易、
かつ、とても高速性が求められています。

となると、どの方法が良いのでしょうか?
・「3つのキー」は数値(int)、文字列(std::stringまたはchar*)、数値(int)の組み合わせでいいですか?
・「とても高速性が求められています」とはどの程度でしょうか?
 例えば、ミリ秒・マイクロ秒単位などでかなりチューニングしないといけない処理なのか、
 それともだいたい1,000,000件を1秒程度で処理できればいいのか、など、
 それによって実装の楽さ(≒バグりにくさ)と高速さのどっちを優先するかが変わってくるかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

usagi
記事: 9
登録日時: 10年前

Re: mapの入れ子

#10

投稿記事 by usagi » 10年前

>・「3つのキー」は数値(int)、文字列(std::stringまたはchar*)、数値(int)の組み合わせでいいですか?

はい。

キー1,数値(int)
キー2,文字列(std::stringまたはchar*)
キー3,数値(int)

データが分類されている順序も「キー1、キー2、キー3」になります。

キー1の値は不定ですが、2種類しかありません。
(例:200と205の時もありますし、500と207などの時もあります)

キー1を動的に mapKey1A , mapKey1B にして
mapKey1A( キー2、キー3 )
mapKey1B( キー2、キー3 )
のようにした方が
map( キー1、キー2、キー3 )
とするより速いでしょうか? それほど変わらないでしょうか?


・「とても高速性が求められています」とはどの程度でしょうか?
 例えば、ミリ秒・マイクロ秒単位などでかなりチューニングしないといけない処理なのか、

メモリDBでは遅いから、mapなどを使ってキャッシュして欲しい。と言われた程度です。
ある会社の顧客(数万人?)の注文が集中してくる箇所になります。

よろしくお願いします

usagi
記事: 9
登録日時: 10年前

Re: mapの入れ子

#11

投稿記事 by usagi » 10年前

返答していただいた方、ありがとうございます。

なんとか解決しました。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: mapの入れ子

#12

投稿記事 by みけCAT » 10年前

できればどのように解決したかを書いていただけるとありがたいです。
フォーラムルール さんが書きました:4. 義務行為

[C言語何でも質問掲示板でのみ適用される事項]

・トピックを立て、解決した場合は「解決しました」とだけ書かず、どうやって解決したか他の人に分かるように書いてからトピックを終了して下さい。
(http://dixq.net/board/board.html)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る