2012-03-24 2 views
1

내 주요 데이터 객체 내 클래스의 특정 인스턴스에 따라 길이의 두 배의 배열입니다. 이러한 객체를 저장/검색하기위한 매우 간단한 해시 테이블을 만들고 싶습니다. 숫자가 숫자 오류가없는 방식으로 생성된다고 가정 할 수 있습니다. 정말보고 싶을 때사용 unordered_map도는

> ./tmp 
x1: 1 
x2: 0 

:

int main() { 
    std::tr1::unordered_map<double*, double*> cache; 

    double x1[] = { 1.0, 3.14 }; 
    double x2[] = { 1.0, 3.14 }; 

    cache[x1] = x1; 

    std::cout << "x1: " << cache.count(x1) << std::endl; 
    std::cout << "x2: " << cache.count(x2) << std::endl; 

    return 0; 
} 

은 위 분명히에만 출력을 제공, 포인터를 비교

> ./tmp 
x1: 1 
x2: 1 

그것은 사용자 정의 해시와 평등을 만드는 방법을 아주 분명 배열의 크기가 컴파일시 일 때 고정 된 이지만 특정 i에 의존하는 사용자 정의 함수를 만드는 방법을 모르는 경우 nstantiation ... 나는 아래의 클래스를 만들었지 만 유용하거나 사용할 수 있을지 잘 모르겠습니다.

struct DoubleRegion 
{ 
    double* p; 
    size_t size; 
}; 

bool operator==(DoubleRegion a, DoubleRegion b) 
{ 
    return a.size == b.size && memcmp(a.p, b.p, a.size) == 0; 
} 

size_t hash(DoubleRegion dr) 
{ 
    size_t h = 0; 
    for (double* p = dr.p; p != dr.p + dr.size; ++p) 
     h ^= hash(*p); 
    return h; 
} 

그리고 그것을 사용 : : 물론

unordered_map<DoubleRegion, DoubleRegion> cache; 

그것은 당신의 문제가

class Hash_double_vec { 

public: 
    int dim; 
    Hash_double_vec(int d) { dim = d; } 

    size_t operator()(const double *x) const{ 
    std::tr1::hash<double> hash_fn; 
    size_t r = hash_fn(x[0]); 
    for(int i=1;i<dim;i++) r ^= hash_fn(x[i]); 
    return r; 
    } 

    bool operator()(const double *x, const double *y) const{ 
    for(int i=1;i<dim;i++) if (fabs(x[i]-y[i]) > 1e-10) return false; 
    return true; 
    } 
}; 

답변

3

한 가지 방법은 복식의 순서로 포인터를 개최 구조체를 생성하는 것입니다 기본 메모리의 수명이 DoubleRegion 수명의 수퍼 셋인지 확인하십시오.

올드 대답 :

키와 값이 될 것입니다 얼마나 큰하는 표준 : : 벡터 사용 런타임 때까지 모르는 경우 :

unordered_map<vector<double>, vector<double>> cache; 

당신이에서 알고있는 경우를 당신이 표준 : 배열을 사용하는 방법에 큰 컴파일 타임 : 당신이 원하는대로 기본 해시 함수 값에 의해 작동 두 경우 모두

unordered_map<array<double, N>, array<double, N>> cache; 

을, 당신은 북동하지 않습니다 커스텀 커스터마이징 정의. 그것은 이러한 개체에 대한 조작의 많은 과학 응용 프로그램이기 때문에

+0

내가 이중 배열을 사용하고, [] 훨씬 적은 메모리와 계산 오버 헤드 STL 이상 : 벡터를 가지고 두 번. 끊임없이 변환하여 해시를 구현할 수는 있지만 분명 비싸다. – fairidox

+0

두 개의 size_t 카운트 (용량에 대한 것, 크기에 대한 것)를 제외하고는 오버 헤드가 거의 없습니다. 그러나 왜 std :: array를 사용할 수 없습니까? N의 가능한 값은 무엇입니까? N을 클래스의 템플릿 매개 변수로 만들 수 있습니까? 그렇다면 std :: array에 전달할 수 있습니다. –

+0

N은 1에서 100 사이의 어딘가에 속하며, 관련된 오버 헤드는 긴 두 자릿수 문자열 조작과 관련됩니다. 즉, 배열 길이가 1 천만 배가되는 double [] 배열을 가지며 크기가 1에서 100 사이의 배열을 무작위로 추출하여 다양한 통계를 계산해야합니다. 나는 아마도 대신 으로 이런 짓을 수도 있지만, 반복자를 구축하는 동안 반복 반대로 A & 배열 [K]를 반복자가 그 벡터를 따라 전달, 새로운 를 구축했다 주위에 전달하는 데 훨씬 쉽게 – fairidox