算法笔记-散列

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;  
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直爱莲子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值