2011-08-04 2 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 백만 개의 요소가 배열되어 있다면, 액세스하는 데 항상 1 단위 시간이 걸립니다. 1 백만 개의 요소 목록이나 대기열이 있다면 하나의 요소에 액세스하는 데 1 백만 단위 시간이 걸릴 수 있습니다. 그러나 만약 당신이 100 만개의 요소를 가진 "지도"를 가지고 있다면, 가장 많은 정보를 얻을 수있는 시간은 19 단위가 될 것입니다. 그래, 배열이 아니기 때문에 꽤 피의 빨랐어. 'unordered_map'은 해시 테이블이기 때문에 보통 충돌이 발생하지 않는 한 더 빠릅니다 ('O (1)'). –

0

배열을 시뮬레이트하는 키/값 연결이 필요한 경우 std :: map을 사용하여 std :: pair를 사용하면됩니다. 그런 다음 색인 (키)을 사용하여 값을 검색하고 실제 값 세트를 신속하게 반복 할 수 있습니다.

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

표준 :지도 배열처럼 행동한다 연산자 []와 같은 구문 편의를 갖는다.

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; 
} 
관련 문제