日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

哈希表的分类,创建,查找 以及相关问题解决

發布時間:2023/11/27 生活经验 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈希表的分类,创建,查找 以及相关问题解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

總體的hash學習導圖如下:

文章目錄

        • 定義
        • 分類
          • 字符hash
          • 排序hash
          • 鏈式hash(解決hash沖突)
            • 創建鏈式hash
            • 查找指定數值
          • STL map(hash)
          • 哈希分類 完整測試代碼
        • 應用(常見題目)
          • 1. 回文字符串(Longest Palindrome)
          • 2. 詞語模式(Word Pattern)
          • 3. 同字符詞語分組(Group Anagrams)

定義

  1. 需要擁有關鍵字 key
  2. 維護一個key和value的映射關系,哈希函數
  3. 最終的hash表擁有直接通過key訪問值的能力

分類

字符hash
/*count letters*/
void hash_char() {int char_map[128] = {0};string s = "aabbbcddeh";for (int i = 0;i < s.length(); ++i) {char_map[s[i]] ++;}for (int i = 0;i < 128; ++i) {if (char_map[i] > 0) {printf("[%c] [%d]\n",i,char_map[i]);}}
}
排序hash
void hash_sort() {int arr[] = {1,100,2,6,998,532,40};int hash_arr[999] = {0};for (int i = 0;i < 7; ++i) {hash_arr[arr[i]] ++;}for (int i = 0;i < 999; i++) {if (hash_arr[i] > 0) {cout << i << endl;}}
}
鏈式hash(解決hash沖突)
創建鏈式hash
struct HashNode
{int data;struct HashNode *next;HashNode(int x):data(x),next(NULL){}
};int get_key(int key, int tabel_len) {return key % tabel_len;
}void insert_hash(HashNode *hash_table[], HashNode *node, int tabel_len) {int key = get_key(node -> data, tabel_len);node ->next = hash_table[key];hash_table[key] = node ;
}
查找指定數值
int get_key(int key, int tabel_len) {return key % tabel_len;
}bool search(HashNode *hash_table[], int value, int tabel_len) {int key = get_key(value,tabel_len);HashNode *head = hash_table[key];while(head) {if (head -> data == value) {return true;}head = head -> next;}return false;
}
STL map(hash)
void stl_hash() {std::map<string, int> map;string a[3] = {"aaa","ssss","ddd"};map[a[0]] = 1;map[a[1]] = 100;map[a[2]] = 301;cout << "stl hash_table is " << endl;for (std::map<string, int>::iterator it = map.begin(); it != map.end(); it ++) {cout << "[" << it -> first.c_str() << "] :" << it -> second << endl; }if (map.find(a[1]) != map.end()) {cout << "sss is in the stl map "  << map[a[1]]<< endl;}
}
哈希分類 完整測試代碼
#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <stdio.h>using namespace std;struct HashNode
{int data;struct HashNode *next;HashNode(int x):data(x),next(NULL){}
};/*count letters*/
void hash_char() {int char_map[128] = {0};string s = "aabbbcddeh";for (int i = 0;i < s.length(); ++i) {char_map[s[i]] ++;}for (int i = 0;i < 128; ++i) {if (char_map[i] > 0) {printf("[%c] [%d]\n",i,char_map[i]);}}
}void hash_sort() {int arr[] = {1,100,2,6,998,532,40};int hash_arr[999] = {0};for (int i = 0;i < 7; ++i) {hash_arr[arr[i]] ++;}for (int i = 0;i < 999; i++) {if (hash_arr[i] > 0) {cout << i << endl;}}
}int get_key(int key, int tabel_len) {return key % tabel_len;
}void insert_hash(HashNode *hash_table[], HashNode *node, int tabel_len) {int key = get_key(node -> data, tabel_len);node ->next = hash_table[key];hash_table[key] = node ;
}bool search(HashNode *hash_table[], int value, int tabel_len) {int key = get_key(value,tabel_len);HashNode *head = hash_table[key];while(head) {if (head -> data == value) {return true;}head = head -> next;}return false;
}void stl_hash() {std::map<string, int> map;string a[3] = {"aaa","ssss","ddd"};map[a[0]] = 1;map[a[1]] = 100;map[a[2]] = 301;cout << "stl hash_table is " << endl;for (std::map<string, int>::iterator it = map.begin(); it != map.end(); it ++) {cout << "[" << it -> first.c_str() << "] :" << it -> second << endl; }if (map.find(a[1]) != map.end()) {cout << "sss is in the stl map "  << map[a[1]]<< endl;}
}int main(int argc, char const *argv[])
{cout << "hash_char" << endl;hash_char();cout << "hash_sort" << endl;hash_sort();const int TABEL_LEN = 11;HashNode *hash_table[TABEL_LEN] = {0};std::vector<HashNode *> hash_node_vec;int test[8] = {1,100,2,6,998,532,40,1};for (int i = 0;i < 8; ++i) {hash_node_vec.push_back(new HashNode(test[i]));}for (int i = 0;i < hash_node_vec.size(); ++i) {insert_hash(hash_table,hash_node_vec[i],TABEL_LEN);}cout << "hash_table" << endl;for (int i = 0;i < TABEL_LEN; ++i) {printf("[%d] ",i);HashNode *head = hash_table[i];while(head) {printf("-> %d", head->data);head = head -> next;}printf("\n");}cout << endl;for (int i =0;i < 10; ++i) {if (search(hash_table, i, TABEL_LEN)) {printf("%d is in the hash_table\n",i);} else {printf("%d is not int the hash_table\n",i);}}stl_hash();return 0;
}

輸出如下:

hash_char
[a] [2]
[b] [3]
[c] [1]
[d] [2]
[e] [1]
[h] [1]
hash_sort
1
2
6
40
100
532
998
hash_table
[0] 
[1] -> 1-> 100-> 1
[2] -> 2
[3] 
[4] -> 532
[5] 
[6] -> 6
[7] -> 40
[8] -> 998
[9] 
[10] 0 is not int the hash_table
1 is in the hash_table
2 is in the hash_table
3 is not int the hash_table
4 is not int the hash_table
5 is not int the hash_table
6 is in the hash_table
7 is not int the hash_table
8 is not int the hash_table
9 is not int the hash_table
stl hash_table is 
[aaa] :1
[ddd] :301
[ssss] :100
sss is in the stl map 100

應用(常見題目)

1. 回文字符串(Longest Palindrome)

問題如下:
已知一個只包括大小寫字符的 字符串,求用該字符串中的字符可以生 成的最長回文字符串長度。
例如 s = “abccccddaa”,可生成的 最長回文 字符串長度為 9,如 dccaaaccd、 adccbccda、 acdcacdca等,都是正確的。

代碼實現如下:

#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <stdio.h>using namespace std;/*
已知一個只包括大小寫字符的 字符串,求用該字符串中的字符可以生 成的最長回文字符串長度。
例如 s = “abccccddaa”,可生成的 最長回文 字符串長度為 9,如 dccaaaccd、 adccbccda、 acdcacdca等,都是正確的。
*/int max_count_palindrome(string s) {if (s.length() == 0) {return 0;}int hash_table[128] = {0};int max_count = 0;int flag = 0;for (int i = 0; i < s.length(); ++i) {if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {hash_table[s[i]] ++;} else {return -1;}}for (int i = 0;i < 128; ++i) {if (hash_table[i] > 0 ) {if(hash_table[i] % 2 == 0) {max_count += hash_table[i];} else {max_count += hash_table[i] - 1;flag = 1;}}}return max_count + flag;
}int main(int argc, char const *argv[])
{string s;cin >> s; cout << max_count_palindrome(s) << endl;return 0;
}

輸出如下:

abccccddaabb
11
2. 詞語模式(Word Pattern)

問題描述如下:

已知字符串pattern與字符串str,確認str是否與pattern匹配。
str與pattern匹配代表字符 串str中的單詞與pattern中的字符一一對應。(其中pattern中只包含小寫字符,str中
的單詞只包含小寫字符,使用空格分隔。) 例如,
pattern = “abba”, str = “dog cat cat dog” 匹配.
pattern = “abba”, str = “dog cat cat fish” 不匹配.
pattern = “aaaa”, str = "dog cat cat dog"不匹配.
pattern = “abba”, str = "dog dog dog dog"不匹配.

實現如下:

#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <stdio.h>using namespace std;/*
已知字符串pattern與字符串str,確認str是否與pattern匹配。
str與pattern匹配代表字符 串str中的單詞與pattern中的字符一一對應。(其中pattern中只包含小寫字符,str中
的單詞只包含小寫字符,使用空格分隔。) 例如,
pattern = “abba”, str = “dog cat cat dog” 匹配. 
pattern = “abba”, str = “dog cat cat fish” 不匹配. 
pattern = "aaaa", str = "dog cat cat dog"不匹配. 
pattern = "abba", str = "dog dog dog dog"不匹配.
*/bool judge_word_partten(string partten, string str) {if ((partten.length() == 0 && str.length() != 0)  || (str.length() == 0)) {return false;}std::map<string, char> hash_table;int used[128] = {0};str.push_back(' ');int i = 0;int j = 0;string tmp = "";cout << partten << " " << str << endl;for(int j = 0;j < str.length(); ++j){if (str[j] == ' ') {if (hash_table.find(tmp) == hash_table.end()) {if (used[partten[i]]) {return false;}used[partten[i]] = 1;hash_table[tmp] = partten[i];} else {if (hash_table[tmp] != partten[i]) {return false;}}tmp = "";i++;} else {tmp += str[j];}}if (i != partten.length()) {return false;}return true;
}int main(int argc, char const *argv[])
{/* code */string partten = "abba";string str = "dog cat cat do";cout << judge_word_partten(partten,str) << endl;return 0;
}

輸出如下:

abba 
dog cat cat do 
0abba 
dog cat cat dog 
1
3. 同字符詞語分組(Group Anagrams)

問題描述:
已知一組字符串,將所有anagram(由顛倒字母順序而構成的 字)放到一起輸出。
例如:[“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] :[“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
返回:[ [“ate”, “eat”,“tea”], [“nat”,“tan”], :[ [“ate”, “eat”,“tea”], [“nat”,“tan”],[“bat”] ]

實現如下:

#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <algorithm>
#include <stdio.h>using namespace std;/*
已知一組字符串,將所有anagram(由顛倒字母順序而構成的 字)放到一起輸出。
例如:["eat", "tea", "tan", "ate", "nat", "bat"] :["eat", "tea", "tan", "ate", "nat", "bat"]
返回:[ ["ate", "eat","tea"], ["nat","tan"], :[ ["ate", "eat","tea"], ["nat","tan"],["bat"] ]
*//*map 建立 string to vector<sting> 的存儲映射*/
std::vector<std::vector<string>> get_group_anagrams(std::vector<string> &str) {std::map<string, std::vector<string> > hash_table;string tmp;std::vector<std::vector<string>> result;for (int i = 0;i < str.size(); ++i){tmp = str[i];sort(tmp.begin(), tmp.end());if (hash_table.find(tmp) != hash_table.end()) {hash_table[tmp].push_back(str[i]);} else {std::vector<string> item;item.push_back(str[i]);hash_table[tmp] = item;}}std::map<string, std::vector<string> >::iterator it = hash_table.begin();for (;it != hash_table.end(); ++it) {result.push_back(it->second);}return result;
}int main(int argc, char const *argv[])
{/* code */std::vector<string> str;for (int i = 0;i < 6; ++i) {string tmp;cin >> tmp;str.push_back(tmp);}std::vector<std::vector<string> > result = get_group_anagrams(str);for (int i = 0;i < result.size(); ++i) {for (int j = 0;j < result[i].size(); ++j) {cout << "[" << result[i][j] << " ] ";}cout << endl;}return 0;
}

輸出如下:

ate eat tea tan nat bat
[bat ] 
[ate ] [eat ] [tea ] 
[tan ] [nat ] 

總結

以上是生活随笔為你收集整理的哈希表的分类,创建,查找 以及相关问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。