【C語言】哈希函數寫法、字符串深度複製

Little trick.html

1 哈希函數

理想的哈希函數保證每一個字符串對應惟一的哈希值。下面這個哈希函數是同窗在項目中遇到的。算法

unsigned int hash(char* s)
{
    unsigned int h=0;
    for(;*s;s++)
        h = *s + h*31;
    return h%HASHSIZE; //predefined hash size
}

能夠看出,這個hash函數遍歷字符串中每一個字符,經過將其ASCII碼計算獲得最終的哈希值h。 這樣來確保前面提到的結果惟一性。 咱們在gdb中驗證一下,有char*類型的字符串s爲nnmm。s的第i個字符用s[i]或者*(s+i)表示。編程

(gdb) p s
$8 = 0x40071c "nnmm"
(gdb) p s[0]
$11 = 110 'n'
(gdb) p s[1]
$12 = 110 'n'
(gdb) p s[2]
$13 = 109 'm'

(gdb) p *s
$9 = 110 'n'
(gdb) p *s+1
$10 = 111
(gdb) p *(s+1)
$14 = 110 'n'
(gdb) p *(s+2)
$15 = 109 'm'

能夠看到,直接打印第i個字符的同時也會輸出該字符的ASCII碼。 第i個字符在公式中轉成ASCII碼,而後算出unsigned int型的h。函數

ASCII碼對照表
輸入圖片說明.net

1.1 哈希函數的對比

[1]中提到編程珠璣中的一個hash函數也是用的相似方法,代碼以下:code

//用跟元素個數最接近的質數做爲散列表的大小
#define NHASH 29989
#define MULT 31

unsigned in hash(char *p)
{
    unsigned int h = 0;
    for (; *p; p++)
        h = MULT *h + *p;
    return h % NHASH;
}

除此以外,[1]還對經常使用字符串哈希函數 BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash進行了量化比較。htm

1.2 哈希函數分類

[2]中把哈希函數分爲以下幾類:blog

  1. 加法Hash;
  2. 位運算Hash;
  3. 乘法Hash;
  4. 除法Hash;
  5. 查表Hash;
  6. 混合Hash;

其中咱們上文的函數屬於乘法Hash,這種類型的Hash函數利用了乘法的不相關性(乘法的這種性質,最有名的莫過於平方取頭尾的隨機數生成算法,雖然這種算法效果並很差)。圖片

jdk5.0裏面的String類的hashCode()方法也使用乘法Hash。不過,它使用的乘數是31。推薦的乘數還有:131, 1313, 13131, 131313等等。字符串

Reference

2 字符串深度複製

char* str_dump(char* s)
{
    int l=strlen(s)+1;
    char* ns=(char*)malloc(l*sizeof(char));
    strcpy(ns,s);//char *strcpy(char* dest, const char *src)
    return ns;// possible be NULL
}
相關文章
相關標籤/搜索