2012-10-09 54 views
1

給定一張地圖,我需要檢索並操作兩個立即存儲的項目。 對我來說,在矢量上工作比較容易,因爲我可以做「iter + 1」或「iter-1」。 雖然對於地圖而言,我很幸運。迭代std :: map的更好方法

例如,我舉一個簡單的例子如下: 注意:在我的真實應用程序中,我不會簡單地減去這些數字。

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; 
} 

問題>有沒有更好的解決方案呢?

謝謝

+1

你到底想幹什麼? 'std :: prev'和'std :: next'有幫助嗎? – Cameron

+0

選擇容器類型取決於廣義用例。如果你做了很多這種類型的迭代,並且你不介意支付搜索性能的代價,那麼使用具有隨機訪問迭代器的容器可能是合理的。 – Chad

+0

@Cameron,很好的瞭解這兩個操作符,但它僅適用於C++ 11。 – q0987

回答

2

不是遞增循環控制中的兩個迭代器(遞增有點慢),只是分配firstItem = secondItem然後遞增secondItem

1

您的代碼將有不確定的行爲,如果映射爲空,但除此之外,它似乎是一個合理的方法,這取決於您的總體目標。由於map迭代器不是隨機訪問,所以不能只增加或減少一個,只能增加/減少。

另一種方法是複製迭代器,然後在循環內部遞增。

+0

感謝您指出範圍檢查。 – q0987

2

你可以用一個迭代器來完成。從頭部移動的增量,以你的循環中,當你打你的地圖結束,這樣退出循環:

map<char,int>::iterator item = mymap.begin(); 
for (;;) { 
    int first = item->second; 
    ++item; 
    if (item == mymap.end()) break; 
    cout << item->second - first << endl; 
} 
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; 
} 
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++) 
{ 
    ... 
} 

我傾向於後者,如果我能做到,用前者只有當我必須這樣做。

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; 
    }); 
相關問題