2009-11-27 54 views
6

由於C++中沒有.resize()成員函數std :: map我想知道,如何獲得一個至多有n個元素的std :: map 。如何獲得std :: map的前n個元素

顯而易見的解決方案是創建一個從0到n的循環,並使用第n個迭代器作爲std :: erase()的第一個參數。

我想知道是否有任何解決方案不需要循環(至少不在我的用戶代碼中),更多的是「STL的方式」。

+1

嗯..我會說使用迭代器循環*是* STL的方式去,不是嗎? – schnaader 2009-11-27 15:04:07

+2

沒有'std :: erase'。使用'std :: map :: erase()' – 2009-11-27 15:48:37

回答

13

您可以使用std::advance(iter, numberofsteps)

+0

+1 - 不知道 - 好的。 – schnaader 2009-11-27 15:13:27

0

爲什麼要調整地圖大小?

在地圖中的元素不會存儲在任何順序 - 第一個「N」並不真正意味着什麼

編輯:
有趣的std ::地圖確實有一個訂單,不知道如何有用這個概念是。
這些條目是否與密鑰具有相同的排序順序?
這是什麼意思?如果您的名稱由SSN鍵入,是否意味着名稱以SSN數字順序存儲?

+0

不是按鍵排序的元素嗎? – 2009-11-27 15:07:52

+0

不符合你的想法,元素在內存中以某種順序排列。有一個哈希算法將密鑰轉換爲索引。 但是key1和key2的元素不一定相鄰。 – 2009-11-27 15:13:21

+3

@mgb 不,這將是一個哈希表。一個std :: map是一個二叉搜索樹(通常是一個紅黑樹)。因此存儲std :: map中的元素的方式使得迭代操作變得簡單和快速。 – Tim 2009-11-27 15:17:59

1

std :: map不是一個列表。沒有「前n個」元素。

順便說一句:如果容器被更改,迭代器將變爲無效。

如果你真的需要一個更小的地圖,你可以遍歷它,並添加到第n個所有元素到一個新的地圖。

+3

那麼,元素是通過他們的關鍵排序是不是他們? – Nailer 2009-11-27 15:06:56

+0

@Nailer:很好,我不知道。此鏈接確認:http://www.cplusplus.com/reference/stl/map/ – ya23 2009-11-27 15:29:36

+1

是的,他們是。但是地圖「最有可能實現爲(平衡)節點樹」(引用「C++編程語言」,Bjarne Stroustrup),而不是列表。所以mymap [n]沒有任何意義。 – EricSchaefer 2009-11-27 15:32:40

3

幾乎所有容器的通用解決方案,如std :: list,std :: map,boost :: multi_index。您只能檢查地圖的大小。

template<class It> 
It myadvance(It it, size_t n) { 
    std::advance(it, n); 
    return it; 
} 

template<class Cont> 
void resize_container(Cont & cont, size_t n) { 
    cont.erase(myadvance(cont.begin(), std::min(n, cont.size())), 
       cont.end()); 
} 
+0

它是無效的std :: advance(),所以它沒有編譯。 – Norbert 2009-11-27 15:24:22

+0

對。我解決了。 – 2009-11-27 15:26:34

+0

+1,但是如果你正在整理這個版本,你就不得不決定'resize_container'運行的是什麼概念。函數和模板參數名稱建議任何容器。函數參數名稱建議任何地圖。正如我寫的,我認爲它實際上可以在任何序列或關聯容器上工作,這不幸意味着它的域是C++分類中的多重組。 – 2009-11-27 15:53:48

1

正確的方法是使用std :: advance。但是,這是一個有趣(緩慢)的方式,允許「在地圖上使用調整大小」。更一般地說,這種技巧可以用於處理矢量但不在地圖上的其他事物。

map<K,V> m; //your map 
vector< pair<K,V> > v(m.begin(), m.end()); 
v.resize(n); 
m = map<K,V>(v.begin(),v.end());