2014-07-24 2 views
1

수명이 다른 데이터 구조에 의해 소유 된 C 문자열 (wchar_t const*)이 있습니다. 문자열에 대한 참조는 포인터로 전달됩니다. 그러한 인스턴스를 unordered_map에 넣고 싶습니다. std::wstring을 임시로 생성하지 않고 std::hash<std::wstring>을 호출하지 않고이 해시를 얻는 데 사용할 수있는 표준 도구가 있습니까?C 문자열의 해시를 검색하는 표준 메커니즘이 있습니까?

std::hash<T*>은 해당 포인터가 가리키는 바이트 스트림 내용의 해시가 아니라 포인터의 해시를 반환한다는 점에 유의하십시오.

+2

라이브러리가 지원하는 경우 라이브러리 기초 TS에서'std :: experimental :: string_view'를 사용할 수 있습니다.이 라이브러리는'string_view'에 해시를 추가합니다. – user657267

+0

"거기 있니?" 아니요, 각 문자에'boost :: hash_combine' 또는 이와 유사한 문자 (예 : [here] (http://stackoverflow.com/questions/6899392/generic-hash-function-for)와 결합 된'std :: hash '을 사용할 수 있습니다. - all-stl-containers)), 내가 알기에 ... ...-). C++ 14에 대한 몇 가지 해싱 관련 제안이 있습니다. 반면에 'void *', 'size_t'변형이 없어도 미치지 만, 그 크기입니다. –

답변

0

언급했듯이 here으로 설명했듯이 C 스타일 문자열의 전문화는 std::hash입니다. 링크 된 페이지에서 인용 :

C 문자열의 전문은 없습니다. std::hash<const char *> 포인터의 값 (메모리 주소)의 해시를 생성하면 은 문자 배열의 내용을 검사하지 않습니다.

따라서, 이러한 문자열에 적용될 때 std::hash 의해 생성 된 해시 값은 실제 내용과 관련이없는, 따라서 필요한 용도에는 적합하지 않다.

무엇을 할 수 있습니까? 임시 구조를 구성하는 것은 배타적이며 안전하지 않은 예외를 초래하는 할당을 포함 할 수 있고 항상 쓸모없는 복사본이 될 수 있기 때문에 게임에서 벗어났습니다. 위의 설명에서 user657267이 지적했듯이 표준 라이브러리가 basic_string_view을 지원하는 경우 해당 std::hash 전문화도 제공해야합니다 (this page).

마지막으로 자신의 해싱 알고리즘을 롤업 할 수 있습니다. 해시 값이 순서가 지정되지 않은 컨테이너에서 사용될 경우 알고리즘의 품질은 성능에 영향을 미치지 만 키의 고유성에는 영향을 미치지 않습니다. 즉, earlier을 발견 한 것처럼 충돌은 없습니다. 테스트 할 수 있습니다. 컴파일러는 C++ 14을 지원하지 않습니다

#include <cstring> 

struct 
    hasher final 
{ 
    constexpr std::size_t 
     operator() 
     (const char * const s) 
     const noexcept 
     { 
      std::size_t h = 0; 

      for (std::size_t i = 0 , l = std::strlen(s) ; i < l ; ++i) 
      { 
       h += h * 65599 + s[i]; 
      } 

      return h^(h >> 16); 
     } 
}; 

경우, constexpr 지정을 제거 할 수있다 :이 예는 X65599의 나를 위해 일했다 알고리즘을 구현합니다. 데이터가 다른 곳에 저장되어 있다면 어쨌든 유용하지 않습니다.

편집 : 방금 제시 한 예제 알고리즘이 좁은 문자열에서 작동한다는 것을 깨달았습니다. 나는 당신이 와이드 캐릭터에서 작동하는 것을 여전히 검색 할 수 있다고 생각한다.

관련 문제