字符串哈希一共有三种,自然溢出法单哈希双哈希,本文用一个例题来解释。

字符串哈希:

        将一段字符串进行加密,比较常用的是进制转化,将每一个字符看成一个进制,转化成一个base进制,比如把一个数由二进制变成十进制,转化完之后的那个数就是那个字符串的hash值。

洛谷的P3370题:

自然溢出法(常用):

        顾名思义,就是利用溢出这一特性来进行的,代码:

#include<iostream>
#include<string.h>
#include<algorithm>

using namespace std;

typedef unsigned long long ull;
const int base = 131;//13331也是可以的
const int N = 10010;
ull a[N];
char s[N];
int n;

ull hashed(char s[])
{
	ull ans = 0;
	for (int i = 0; i < strlen(s); i++)
	{
		ans = ans * base + (ull)s[i];//利用自然数的溢出,超过2*64自动溢出,节省了很多的时间
	}
	return ans;
}

int main()
{
	int res = 0;
	ios::sync_with_stdio(false);
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> s;
		a[i] = hashed(s);
	}
	sort(a + 1, a + n + 1);
	for (int i = 2; i <= n; i++)
	{
		if (a[i] != a[i - 1])
		{
			res++;
		}
	}
	cout << res + 1 << endl;
	return 0;
}

单哈希(找一个尽可能大的质数,才更多的减少哈希冲突的出现):

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

typedef unsigned long long ull;
const int N = 10010;
ull base = 131;
ull a[N];
char s[N];
int n;
ull mod = 212370440130137957ll;//是质数,如果用19260817只有80分
ull hashs(char s[])
{
    int len = strlen(s);
    ull ans = 0;
    for (int i = 0; i < len; i++)
    {
        ans = (ans * base + (ull)s[i]) % mod;
    }
    return ans;
}
main()
{
    int res = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> s;
        a[i] = hashs(s);
    }
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++)
    {
        if (a[i] != a[i - 1])
        {
            res++;
        }
    }
    cout << res << endl;
}

双哈希(为了减少哈希冲突,就使用两个质数,进行双重的判断):

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

typedef unsigned long long ull;
const int N = 10010, base = 131;
int mod1 = 19260817;//第一个质数
int mod2 = 19260813;//第二个质数
string aa;
int n;

struct nb
{
	ull x, y;
};

ull hash1(string aa)
{
	ull ans = 0;
	for (int i = 0; i < aa.size(); i++)
	{
		ans = (ans * base + (ull)aa[i]) % mod1;
	}
	return ans;
}

ull hash2(string aa)
{
	ull ans = 0;
	for (int i = 0; i < aa.size(); i++)
	{
		ans = (ans * base + (ull)aa[i]) % mod2;
	}
	return ans;
}

int cmp(nb s1, nb s2)
{
	return s1.x < s2.x;
}
int main()
{
	int res = 0;
	nb a[N];
	ios::sync_with_stdio(false);
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> aa;
		a[i].x = hash1(aa);
		a[i].y = hash2(aa);
	}
	sort(a + 1, a + n + 1, cmp);
	for (int i = 1; i <= n; i++)
	{
		if (a[i].x != a[i - 1].x || a[i].y != a[i - 1].y)
		{
			res++;
		}
	}
	cout << res << endl;
	return 0;

}

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐