【C++】字符串|比较类问题模板

这一篇文章主要涉及到字符串间进行比较、判断相等等问题的算法。

字符串哈希

哈希hash:哈希函数又叫散列函数,简单说就是把一段任意字符映射为一个与之对应的整数。要求字符串与数字一一对应。密码学和项目中常见的md5,sha1,sha256都是现代常用的哈希算法(均不可逆,均用16进制数表示)

竞赛中使用的是最基本的,基于质数映射的哈希函数。

题目:P3370 【模板】字符串哈希https://www.luogu.com.cn/problem/P3370

C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;
using ull = unsigned long long;
// A naive prime
constexpr int prime = 19260817;

ull gethash(string& s)
{
	ull cur = 0;
	for (auto& i : s)
	{
		cur *= prime;
		cur += i;
	}
	return cur;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n;
	string tmp;
	cin >> n;
	vector<ull> sts;
	int res = n;
	while (n--)
	{
		cin >> tmp;
		sts.emplace_back(gethash(tmp));
	}
	sort(sts.begin(), sts.end());
	for (int i = 1; i < sts.size(); i++)
	{
		if (sts[i] == sts[i - 1]) res--;
	}
	cout << res << endl;
	return 0;
}

哈希碰撞

上面提到了原字符串应与哈希结果一一对应(充要)。显然存在一些特殊的字符串,可以使得他们恰巧算出了同一个哈希值,这种现象就是哈希碰撞。

最小表示法

什么是最小表示法:一个字符串s经过轮换得到的字典序最小的串i,称i为s的最小表示。

例子:s="acacab", -> i="abacac";

很容易写出每种排列都试一下的暴力算法,但是显然这是O(n^2)的。

Booth 算法

存在一种O(n)的算法可以快速求出最小表示。主要思想与KMP类似,即利用已比较部分跳过无用部分。

题目:P13270 【模板】最小表示法https://www.luogu.com.cn/problem/P13270

C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n;
	string s;
	cin >> n >> s;
	int i = 1, j = 0, k = 0;
	while (i < n && j < n)
	{
		for (k = 0; k < n; k++)
		{
			if (s[(i + k) % n] != s[(j + k) % n]) break;
		}
		if (s[(i + k) % n] > s[(j + k) % n]) i += k + 1;
		else j += k + 1;
		if (i == j) j++;
	}
	int res = min(i, j);
	for (int x = res; x < res + n; x++)
	{
		cout << s[x % n];
	}
	cout << endl;
	return 0;
}

目前有关字符串的比较相关问题就这些内容。希望我以后遗忘可以慢一点。。。同时如果这也能帮到你,我很荣幸。真的。。

版权声明:
作者:Toms Project
链接:https://blog.projectoms.com/pages/1680.html
来源:Toms Project 官方博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录