2

C ++では、3つのキーに基づいて構造体の値を集計するにはどうすればよいですか?

Perlでは、ハッシュのハッシュを使用してこれを行います(たとえば、$ hash {$ key1} {$ key2} {$ key3} {'call_duration'} + = 25);

私はC++の完全な初心者なので、適切なアプローチを提案していただけますか?

std ::mapを使用してC++でのネストされたハッシュの同等物について説明しているSOに関するトピックを見てきましたが、これはパフォーマンスの面で低速であり、通信事業者のレコードを処理する必要があるため、パフォーマンスが重要であると述べています。

テンプレートライブラリや、構文と考え方がPerlに似ているはずの何かを使用するアプローチに従う必要はありませんが、同様のことを行う必要がある場合は、それを実装するための高速で適切な方法を共有してください。

私は主にC++98標準に制限されています(技術リーダーは、コンパイラーによってサポートされており、非常に有益であるという条件で、新しい機能の使用を許可しています)。

説明が混乱している場合はお詫び申し上げます。よろしくお願いいたします。

編集:コンパイラのバージョンはGCC 4.1.2であり、ライブラリとしてtr1/functionalをインポートすることはそれによって嫌われていません。

編集:参加してくれたすべての人、特に私の愚かな質問に我慢してくれたBartekとRostに感謝します。私は実際に仕事に取り掛かることができたので、ロストの答えを選ぶことにしました!:)

4

2 に答える 2

2

簡単な解決策は、3 つのキーを集約した構造体を使用し、それをキーとして使用することです。

struct Key
{
    Type1 Key1;
    Type2 Key2;
    Type3 Key3;

    // I forgot about the comparator - you have to provide it explicitly
};

言語に多少制限があるため、コンパイラがサポートしているかどうかを確認してくださいstd::hash_map

std::hash_map<Key, TValue> Data;

そうでない場合は、いつでも使用できますboost::unordered_map

ただし、他の誰かが同じ問題に遭遇した場合、「適切な解決策」は次のとおりです。

std::unordered_map<std::tuple<Type1, Type2, Type3>, TValue>;

編集:使用例

struct Key
{
    int Int;
    float Float;
    string String;
    // add ctor and operator<
};

std::hash_map<Key, int> Data;

Data[Key(5, 3.5f, "x")] = 10;
于 2012-09-26T09:22:20.190 に答える
2

Commonstd::mapが適しています。通常、ほとんどの場合、そのパフォーマンスは問題になりません。ハッシュは要素への一定時間のアクセスを提供し、ツリーベースのマップは対数時間を提供しますが、実際には一定時間は対数よりも大きい可能性があります-それは特定の実装と特定のデータに依存します. コンテナに一度入力してから、キーの変更/挿入/削除なしでデータのみを更新する場合は、 sortedstd::vectorまたはLoki::AssocVector.

最初に試してstd::map(またはstd::setキーが実際にデータの一部である場合)、それから遅すぎるかどうかを判断してください。例:

// Composite key definition
struct CompositeKey
{
   int key1;
   std::string key2;
   AnotherType key3;

   CompositeKey(int i_key1, const std::string& i_key2, AnotherType i_key3):
      key1(i_key1), key2(i_key2), key3(i_key3)
   {}

   bool operator < (const CompositeKey& i_rhs) const
   {
      // You must define your own less operator for ordering keys
   }
};

// Usage
std::map<CompositeKey, Data> aggrData;

aggrData[CompositeKey(0, "KeyString", AnotherType())] = Data();

if(aggrData.find(CompositeKey(0, "KeyString", AnotherType())) != aggrData.end())
{
   // Process found data
}

さらにパフォーマンスを調査するには、次を試すことができます。

これらのコンテナはすべて類似したインターフェースを備えているため、カプセル化することは難しくなく、必要に応じて実装を簡単に切り替えることができます。

于 2012-09-26T09:54:35.820 に答える