빠른 문자열을 해싱 알고리즘을 저렴한 충돌 요금이 32 비트 정수[마감]

StackOverflow https://stackoverflow.com/questions/114085

  •  02-07-2019
  •  | 
  •  

문제

나의 많은 관련이라는 것을 내가 하고 싶 빠른 검색을 한다.는"aardvark"항상"땅 돼지"도처에,그렇게 해싱하는 문자열과 재사용하는 정수 잘 작동 속도를 비교할 수 있습니다.전체 집합의 이름은 알 수 없음(그리고 시간에 따라 변경).What 빠른 문자열을 해싱 알고리즘을 생성하는 작은(32 16)비트 값이 낮은 충돌 평가?

보고 싶은 최적화된 구현하는 C/C++.

도움이 되었습니까?

해결책

하의 FNV 개 해 귀하의 요구 사항을 충족합니다.그들은 빠른,그리고 생산을 매우 균등하게 배 출력이 있습니다.

다른 팁

잡음 해시 은 매우 좋다.

에 대한 고정된 문자열 설정을 사용하면 됩.

는 경우에 귀하의 문자열 설정 변경할 수 있는 기회를 제공합니다 hash function.는 항목에서 논의되었습기:

무엇 최고의 해싱하는 알고리즘을 사용하는 stl 문자열을 사용할 때 해시 맵?

좋은 기사eternallyconfuzzled.com.

Jenkins'One-at-a-Time 해쉬한 문자열은 다음과 같이 보일 것입니다:

#include <stdint.h>

uint32_t hash_string(const char * s)
{
    uint32_t hash = 0;

    for(; *s; ++s)
    {
        hash += *s;
        hash += (hash << 10);
        hash ^= (hash >> 6);
    }

    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);

    return hash;
}

다른 솔루션은 더 나은 수에 따라 사용 사례 구금 문자열.이 얼마나 기호 작동 예시패키지.

는 억류된 문자열은 문자열체는 값은 실제의 주소는 문자열이다.그래서 당신은 만들기를 억류된 문자열체를 확인하여 글로벌 테이블:는 경우 문자열은 거기에서,당신을 초기화 억류된 문자열의 주소는 문자열입니다.하지 않을 경우,당신은 그것을 삽입한 다음 초기화신의 억류된 문자열입니다.

이 의미는 억류된 두 문자열 내에서 동일한 문자열 값이 같은 주소입니다.그래서 만 N 의 수감되는 문자열에는 시스템의 특성은 다음과 같습니다.

  • 느린 건설(필요 조회 및 가능한 메모리 할당)
  • 필요한 글로벌 데이터 및 동기화의 경우에는 동시 스레드
  • 비교 O(1),기 때문에 당신이 비교를 주지 않는,실제 문자열 바이트(즉,정렬,하지만 잘 작동 되지 않습니다 알파벳 일종).

환호

Carl

왜 당신은 단지 사용 을 향상 라이브러리? 의 해싱 기능을 사용하는 간단하고는 대부분의 재료에 부 곧 C++표준입니다.그것의 일부를 이미입니다.

Boost 해시만큼 쉽

#include <boost/functional/hash.hpp>

int main()
{
    boost::hash<std::string> string_hash;

    std::size_t h = string_hash("Hash me");
}

을 찾을 수 있습에서 향상 boost.org

그것은 결코 늦은 좋은 주고 난 사람들에 관심이 나의 결과입니다.

나는 데 필요한 해쉬 기능을 읽은 후 이 게시물을하고 연구의 비트에서 링크가 주어진 여기에,나는 이 변화의 다니엘 J 번스타인의 알고리즘을 사용하는 흥미로운 테스트:

unsigned long djb_hashl(const char *clave)
{
    unsigned long c,i,h;

    for(i=h=0;clave[i];i++)
    {
        c = toupper(clave[i]);
        h = ((h << 5) + h) ^ c;
    }
    return h;
}

이 변화는 해시 문자열을 무시하는 경우 가장 필요로 해시 사용자는 로그인 자격 증명입니다.'clave'는'키'에서 스페인어입니다.나는 스페인어 그러나 그 어머니는 혀가 프로그램이 작성되었습니다.

만,나는 프로그램을 생성하는 사용자 이름에서'test_aaaa'에서'test_zzzz',그리고-할 긴 문자열-가 그들에게 임의의 도메인이트:'cloud-nueve.com','yahoo.com','gmail.com'및'hotmail.com'.따라서 그들 각각 다음과 같을 것이다:

test_aaaa@cloud-nueve.com, test_aaab@yahoo.com, 
test_aaac@gmail.com, test_aaad@hotmail.com and so on.

여기에서 출력의 테스트-'Colision entre XXX y XXX'는'충돌의 XXX XXX'.'palabras'의'단어가'및'총'은 동일한 모두어.

    Buscando Colisiones...
    Colision entre 'test_phiz@hotmail.com' y 'test_juxg@cloud-nueve.com' (1DB903B7)
    Colision entre 'test_rfhh@hotmail.com' y 'test_fpgo@yahoo.com' (2F5BC088)
    Colision entre 'test_wxuj@hotmail.com' y 'test_pugy@cloud-nueve.com' (51FD09CC)
    Colision entre 'test_sctb@gmail.com' y 'test_iohw@cloud-nueve.com' (52F5480E)
    Colision entre 'test_wpgu@cloud-nueve.com' y 'test_seik@yahoo.com' (74FF72E2)
    Colision entre 'test_rfll@hotmail.com' y 'test_btgo@yahoo.com' (7FD70008)
    Colision entre 'test_wcho@cloud-nueve.com' y 'test_scfz@gmail.com' (9BD351C4)
    Colision entre 'test_swky@cloud-nueve.com' y 'test_fqpn@gmail.com' (A86953E1)
    Colision entre 'test_rftd@hotmail.com' y 'test_jlgo@yahoo.com' (BA6B0718)
    Colision entre 'test_rfpp@hotmail.com' y 'test_nxgo@yahoo.com' (D0523F88)
    Colision entre 'test_zlgo@yahoo.com' y 'test_rfdd@hotmail.com' (DEE08108)
    Total de Colisiones: 11
    Total de Palabras  : 456976

는 것은 나쁘지 않다,11 의 충돌의 456,976(물론을 사용하여 가득 차있는 32 비트로 테이블 길이).

실행하는 프로그램을 사용하여 5 문자,그가'에서 test_aaaaa'에서'test_zzzzz',실제로 실행의 메모리 건물이다.아래에 출력된다.'No hay memoria para insertar XXXX(insertadas XXX)'의'있지 않은 남아있는 메모리를 삽입하 XXX(XXX 삽입하는)'.기본적으로 malloc()에 실패했다는 점이다.

    No hay memoria para insertar 'test_epjcv' (insertadas 2097701).

    Buscando Colisiones...

    ...451 'colision' strings...

    Total de Colisiones: 451
    Total de Palabras  : 2097701

을 의미하는 단 451 충돌에 2,097,701 문자열입니다.참고가 없는 경우가 있었 2 개 이상의 충돌당 코드입니다.는지 확인 그것은 좋은 해시 나를 위해,무엇이 필요로 변환하는 로그인 ID40 비트 고유 id 인덱.그래서 나는 이를 사용하여 로그인 자격증명을 변환하는 32 비트 해시고 사용하여 추가 8 비트를 처리하는 최대 255 개의 충돌당 코드를 찾고 테스트 결과는 것은 거의 불가능을 생성합니다.

희망이 사람에게 유용하다.

편집:

다음과 같이 테스트 상자가 AIX,나는 그것을 실행하는 사용 LDR_CNTRL=MAXDATA=0x20000000 를 제공 그것은 더 많은 메모리고 더 이상 실행,결과는 여기:

Buscando Colisiones...총 de Colisiones:2908 총 de Palabras:5366384

는 2908 후 5,366,384 하려고!!

매우 중요한:컴파일과 함께 프로그램-maix64(그래서 사용되는 64 비트),수의 충돌 0 에 대한 모든 경우에!!!

보 GNU 면 됩.

해쉬 기능은 매우 좋은,그리고 일부 벤치마크/비교는,일반적으로 해시 기능 C.에 따라 당신이 무엇을 원하는(그것은 완전히 분명)을 고려할 수 있습니다 같은 뭔가 cdb 대신 합니다.

밥 젠킨스는 많은 해시 사용할 수 있는 기능, 모두는,빠르고 저렴한 충돌 요금입니다.

당신은 무엇을 볼 수 있습니다.NET 에서 사용하는 문자열입니다.GetHashCode()메서드를 사용하는 반사체.

나는 것을 짐작하는 Microsoft 상당한 시간 최적화이다.그들이 인쇄되는 모든 문제를 일괄적으로 너무는 그것을 변경될 수 있다.그래서 명확하게 그것은 그들의"성과 레이더를 조정";-)

것은 아주 사소한 포트는 C++너무 나는 생각했을 것입니다.

거기에 몇 가지 좋은 토론에서 이 이전 질문

와 좋은 방법에 대한 개요를 선택하는 해쉬 기능뿐만 아니라,통계량의 분포에 대한 여러 가지 일반적인 것들

여기서 설명하는 방법으로 구현하는 자: http://www.devcodenote.com/2015/04/collision-free-string-hashing.html

조각에서 게시물:

고 말하는 경우에 우리는 캐릭터 설정은 자본의 영어 문자,그 길이의 캐릭터 설정은 26 일이 될 수 있습에 의해 표현된 숫자 0B 의 숫자 1,C 에 의하여 숫자 2 까 Z 에 의하여 숫자 25.지금할 때마다 우리는 원하는 지의 문자열 이 캐릭터 설정하는 고유 번호,우리가 수행하는 동 변환했던 것처럼 우리는 경우에는 바이너리 형식

CRC32.가에 대해 조의 링크에서 google 습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top