2011-08-04 47 views
1

我有一個不一定是滿的數組。關於在C++中迭代數組的問題

它可能非常稀疏。

有沒有好的方法來遍歷這個數組而不訪問所有可能的索引? (C++數組迭代器?)

或者,即使我使用數組迭代器,它會沒有什麼不同,訪問每個索引和檢查值?

+0

數組總是「滿」,它們總是連續的內存序列。沒有「漏洞」,你需要跳過。 –

+1

@Kerrek:不,但它有「邏輯」漏洞。我認爲指針數組中的NULL項是「漏洞」。 –

+1

如何在不查看索引中包含的內容的情況下知道要跳過哪個索引? – pmr

回答

4

是的,如果您使用迭代器,它與訪問每個索引並檢查值是一樣的,並且沒有好辦法跳過邏輯漏洞。你可以保留一個好的索引列表,但是如果你這樣做了,那麼爲什麼不直接使用一個列表來存儲數據呢?

如果您的數據非常稀疏,則根據您的應用程序,更好的數據結構可能是std::map或甚至std::unordered_map。這些都有不錯的查找時間,而不會浪費太多空間,就像數組必須的那樣。

+0

只是想知道......你說'std :: map'會有不錯的查找時間。這是否意味着O(1)像數組?或者O(n)像隊列一樣? – user482594

+0

@ user482594'O(lg n)'實際上 - 在一個數組和隊列之間,但更接近一個數組。例如,如果您有一百萬個元素的數組,則總是需要1個單位時間來訪問任何元素。如果您有一百萬個元素的列表或隊列,則可能需要100萬個單位的時間才能訪問任何元素。但是如果你有一個包含100萬個元素的「地圖」,那麼可能需要19個單位的時間來訪問任何一個元素。所以是的,這不是一個數組,它非常流血。請注意''unordered_map',因爲它是一個散列表,通常會更快('O(1)',除非你有衝突)。 –

0

如果您需要一個模擬數組的鍵/值關聯,只需使用一個包含std :: pair的std :: map即可。然後,您可以使用索引(鍵)檢索您的值,並快速遍歷您的實際值集合。

http://en.cppreference.com/w/cpp/container/map

的std ::地圖具有語法便利設施,如操作符[]將充當像陣列。

1

準數組是你試圖構建的。我建議你找一個爲你做這個的圖書館!

0

如果您確實需要堅持使用基於陣列的解決方案boost::filter_iterator可能會有用。這裏是整數陣列的一個小例子:

#include <algorithm> 
#include <iostream> 
#include <boost/iterator/filter_iterator.hpp> 

struct is_not_null { 
    bool operator()(int* t) { 
    return t != NULL ? true : false; 
    } 
}; 

int main() 
{ 
    int* a[] = {NULL, NULL, NULL, NULL, NULL, NULL }; 
    a[0] = new int[3]; 
    a[0][0] = 1; a[0][1] = 2; a[0][2] = 3; 
    a[3] = new int[3]; 
    a[3][0] = 3; a[3][1] = 4; a[3][2] = 5; 
    a[5] = new int[3]; 
    a[5][0] = 5; a[5][1] = 6; a[5][2] = 7; 

    typedef int** base_iterator; 
    typedef boost::filter_iterator<is_not_null, base_iterator> 
    FilterIter; 

    for(FilterIter it = boost::make_filter_iterator<is_not_null>(a, a + 6); 
     it != boost::make_filter_iterator<is_not_null>(a + 6, a + 6); 
     ++it) { 
    std::cout << (*it)[0] << " " << (*it)[1] << " " << (*it)[2] << std::endl; 
    } 

    // nevermind the leaks 
    return 0; 
}