hash算法的思想
- 散列方法的主要思想是根据结点的关键码值来确定其存储地址
以关键码值K为自变量,通过一定的函数关系h(K)(称为散列函数),计算出对应的函数值来,把这个值解释为结点的存储地址,将结点存入到此存储单元中。检索时,用同样的方法计算地址,然后到相应的单元里去取要找的结点。通过散列方法可以对结点进行快速检索。散列(hash,也称“哈希”)是一种重要的存储方式,也是一种常见的检索方法。
整数出现的个数
整数出现的个数
利用的hash思想
因为输入的数据都没有超过100的,所以直接就是遍历所有的N
设置一个数组hash,然后输入数据到里面,然后输出i(不为0),局可以输出
然后输出个数
#include<iostream>
using namespace std;
const int N = 1001;
int hash[N] = { 0 };
int main()
{
int n;
cin >> n;
int x;
for (int i = 0; i < n; i++)
{
scanf_s("%d", &x);
hash[x]++;
}
for (int i = 0; i <= 100; i++)
{
if (hash[i])
{
printf("%d %d\n", i, hash[i]);
}
}
}
字符串出现个数
先进行输入字符串,利用hash方法,需要确立两个点
1.输入数据的范围
2.全部hash数组确立的范围=数据的数目
- 注意的点
c++中定义和赋值一个字符串
char a[10];
cin >> a;
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int N1 = 1001;
const int N2 = 26;
int get(char v)
{
return v- 'a';
}
int main()
{
int hash[N2] = { 0 };
char str[N1];
cin >> str;
int n = strlen(str);
for (int i = 0; i < n; i++)
{
hash[get(str[i])]++;
}
//从a开始到z结束,从26个字母中进行遍历了
for (char c = 'a'; c <= 'z'; c++)
{
if (hash[get(c)])
{
printf("%c %d", c, hash[get(c)]);//运用get函数表示的是输出有多少个相同的个数
}
}
return 0;
}
整数是否出现
注释:
整数是否出现,利用hash算法进行运算
先将hash数组全部赋值成false
然后再输出第一排数组中的数据,并且改成true
在输出下一组数组的时候,进行判断,如果在输出数据中hash是真的还是假的
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1001;
int main()
{
int hash[N] = { false };
int n, m;
cin >> n;
int x;
for (int i = 0; i < n; i++)
{
scanf_s("%d", &x);
hash[x] = true;
}
cin >> m;
for (int i = 0; i < m; i++)
{
scanf_s("%d", &x);
printf("%d", hash[x] ? 1 : 0);
printf(i != m - 1 ? " " : "\n");
}
return 0;
}
整数出现的个数2
- 这个相对就简单一些,就是真的直接就用hash算法进行操作了
就是说在数组一中输入一些数据,然后进行记录分别数据的个数的多少
然后再m数组中输出符合n中数据的多少
#include<iostream>
using namespace std;
const int N = 1001;
int main()
{
int n, m;
cin >> n >> m;
int hash[N] = { 0 };
int x;
for (int i = 0; i < n; i++)
{
cin >> x;
hash[x]++;
}
for (int i = 0; i < m; i++)
{
cin >> x;
if (hash[x])
{
printf("%d%d",x, hash[x]);
printf(i != m - 1 ? " " : "\n");
}
}
return 0;
}
字符是否出现
字符时候出现过
判断字符串s2是否在s1出现过,
1.利用hash数组(范围是26,只是简单的考虑是否出现过,所以只是需要对应26个字母的数目就行了)false全部
设置成false,然后再依次的将s1中的字符进行改变
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int N = 26;
const int N2 = 1001;
char s1[N2];
char s2[N2];
int getchar(char c)
{
return c - 'a';
}
int main()
{
int hash[N] = { false };
cin >> s1 >> s2;
int len1 = strlen(s1);
int len2 = strlen(s2);
for (int i = 0; i < len1; i++)
{
hash[getchar(s1[i])] = true;
}
for (int i = 0; i < len2; i++)
{
printf("%d\n", hash[getchar(s2[i])]);
printf(i != len2 - 1 ? " " : "\n");
}
return 0;
}
字符串出现的个数
//运用布尔函数进行统计和记录,不需要像上面那样进行了
#include<iostream>
#include<string>
using namespace std;
const int N = 1001;
char s1[N];
char s2[N];
int main()
{
bool hash[N] = { false };
cin >> s1 >> s2;
int len1 = strlen(s1);
int len2 = strlen(s2);
for (int i = 0; i < len1; i++)
{
hash[s1[i]] = true;
}
for (int i = 0; i < len2; i++)
{
printf("%d", hash[s2[i]]);
printf(i != len2 ? " " : "\ ");
}
}
2-sum-hash
#include <cstdio>
const int MAXN = 100000;
const int MAXK = 1000001;
int a[MAXN], hashTable[MAXK] = {false};
int main () {
int n, k;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
hashTable[a[i]] = true;
}
int ans = 0;
for (int i = 0; i < n; i++) {
if (k - a[i] >= 0 && hashTable[k - a[i]]) {
ans++;
}
}
printf("%d", ans / 2);
return 0;
}
字符串出现的次数
开始思考的半成平,但是值得思考
#include<iostream>
#include<string>
using namespace std;
const int N = 1001;
int get(char *p)
{
return *p - 'A' + *(p + 1) - 'A' + *(p + 2) - 'A';
}
int main()
{
int get(char* p);
int hash[N] = { false };
char s1[N][3], s2[N][3];
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf_s("%c", s1[i][j]);
}
}
}
用字符串进行最优解答
注意:字符a[N] 中不能够存字符串
//字符串出现的次数
//问题:输入n个字符串(大写),然后输出查询的字符串m个
//#include <cstdio>
//
//const int MAXN = 26 * 26 * 26;
//const int MAXL = 1001;
//char str[MAXL];
//int hashTable[MAXN] = { 0 };
//
//int getHashKey(char s[])
// {
// return (s[0] - 'A') * 26 * 26 + (s[1] - 'A') * 26 + (s[2] - 'A');
//}
//
//int main() {
// int n, m;
// scanf("%d", &n);
// for (int i = 0; i < n; i++)
// {
// scanf("%s", str);
// hashTable[getHashKey(str)]++;//将字符串转换成整数,然后用直接定址法进行确定
// }
// scanf("%d", &m);
// for (int i = 0; i < m; i++) {
// scanf("%s", str);
// printf("%d", hashTable[getHashKey(str)]);//直接输入m个字符串,如果出现有,那么就会输出上面指定的数目
// printf(i < m - 1 ? " " : "\n");//就是i不等于m-1的时候就会输出“ ”
// }
// return 0;
//}
//
集合求交
#include <cstdio>
const int MAXV = 10001;
bool hashTable[MAXV] = { false };//先将hashtable数组全部的定义成false
int main()
{
int n, m, x;
scanf_s("%d%d", &n, &m);
for (int i = 0; i < n; i++)
{
scanf_s("%d", &x);
hashTable[x] = true;//直接定地址法,输入的数,直接对应到数组hashtable之中,然后进行
//改变定义true
}
bool isFirst = true;
for (int i = 0; i < m; i++)
{
scanf_s("%d", &x);
if (hashTable[x])
{
if (!isFirst)//这是利用false和true进行输入数据之间的空格
{
printf(" ");
}
printf("%d", x);
isFirst = false;
}
}
return 0;
}
集合求并
#include <cstdio>
const int MAXV = 10001;
bool hashTable[MAXV] = { false };//先对于数组hashtable进行复制false
int main() {
int n, m, x;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", &x);
hashTable[x] = true;
}
for (int i = 0; i < m; i++) {
scanf("%d", &x);
hashTable[x] = true;
}
bool isFirst = true;
for (int i = 1; i < MAXV; i++) {
if (hashTable[i]) {
if (!isFirst) {
printf(" ");
}
printf("%d", i);
isFirst = false;
}
}
return 0;
}
集合求差
#include <cstdio>
const int MAXV = 10001;
bool hashTable[MAXV] = {false};
int main () {
int n, m, x;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", &x);
hashTable[x] = true;
}
for (int i = 0; i < m; i++) {
scanf("%d", &x);
hashTable[x] = false;
}
bool isFirst = true;
for (int i = 0; i < MAXV; i++) {
if (hashTable[i]) {
if (!isFirst) {
printf(" ");
}
printf("%d", i);
isFirst = false;
}
}
return 0;
}