1

マップが与えられたら、すぐに保管された 2 つのアイテムを取得して操作する必要があります。私にとっては、「iter + 1」または「iter - 1」を実行できるため、ベクトルでの作業がより簡単になります。マップの場合、私は運が悪いです。

たとえば、次のような簡単な例を示します。 注: 実際のアプリケーションでは、これらの数値を単純に減算するわけではありません。

int main ()
{
    map<char,int> mymap;
    map<char,int>::iterator it;

    mymap['b'] = 100;
    mymap['a'] = 200;
    mymap['c'] = 300;

    // show content:
    map<char,int>::iterator firstItem  = mymap.begin();
    map<char,int>::iterator secondItem = ++mymap.begin();

    for ( ; secondItem != mymap.end(); ++firstItem, ++secondItem )
        cout << secondItem->second - firstItem->second << endl;

    return 0;
}

質問> これに対するより良い解決策はありますか?

ありがとうございました

4

6 に答える 6

2

単一のイテレータで実行できます。次のように、インクリメントをヘッダーからループの途中に移動し、マップの最後に到達したらループを終了します。

map<char,int>::iterator item  = mymap.begin();
for (;;) {
    int first = item->second;
    ++item;
    if ( item == mymap.end()) break;
    cout << item->second - first << endl;
}
于 2012-10-09T15:32:30.503 に答える
2

マップが空の場合、現在のループは未定義の動作を示します。

ループは次のように書き換えることができます (より簡単に、空のマップをチェックします)。

int main(int argc, char * argv[])
{
    map<char,int> mymap;
    map<char,int>::iterator it;

    mymap['b'] = 100;
    mymap['a'] = 200;
    mymap['c'] = 300;

    for ( it = ( mymap.begin() == mymap.end() ? mymap.end() : std::next(mymap.begin()) ) ; it != mymap.end(); ++it )
        cout << it->second - std::prev(it)->second << endl;

    return 0;
}
于 2012-10-09T15:33:35.650 に答える
2

これはスタイルの問題です。たとえば、次のことができます。

auto first = m.begin();

if (first != m.end())
{
    auto second = first;
    second++;

    for (; second != m.end(); first = second++)
    {
        ...        
    }
}

マップが空の場合は、よりエレガントに救済することもできます。たとえば、次のことができます。

if (m.empty()) return;

auto first = m.begin(), second = first;

for (second++; second != m.end(); first = second++)
{
   ...
}

できれば後者を優先し、必要な場合にのみ前者を使用します。

于 2012-10-09T15:34:30.300 に答える
2

ループ制御で両方の反復子をインクリメントする代わりに (インクリメントは少し遅い)、割り当ててfirstItem = secondItemからインクリメントするだけsecondItemです。

于 2012-10-09T15:31:56.587 に答える
1

マップが空の場合、コードは未定義の動作をしますが、それ以外は全体的な目標に応じて合理的なアプローチのようです。mapイテレータはランダム アクセスではないため、単純に加算または減算することはできず、インクリメント/デクリメントのみを行うことができます。

もう 1 つの方法は、反復子のコピーを作成し、ループ内でインクリメントすることです。

于 2012-10-09T15:30:45.843 に答える
0

良くも悪くもありません。ただの代替案です。

if (map.size() >=2)
std::accumulate(
  ++mymap.begin(),
  mymap.end(),
  mymap.begin(),
  [](mymap_type::const_iterator iprev, mymap_type::value_type const& entry)->mymap_type::const_iterator
  { 
    /* do something */;
    return ++iprev; 
  });
于 2012-10-09T15:36:15.330 に答える