c++ - C++ hashCode - 处理大数(+ mod 操作)
问题描述
我正在开发一个项目,该项目涉及对Java hashCode()散列函数进行编程,
公式.
输入字符串(即“A 添加触发单元 C”)是随机生成的并存储在 .txt 文件中。此外,如果结果哈希不在范围内(0 < hash < N),则需要调整=> hash % N)。
我在使用 hashCode() 算法时遇到了问题,因为字符串中只有一个字符的结果太大(即 1.408 * 10^30)而无法存储在常规变量中。我尝试使用一些允许您存储非常大的数字的库,但如果哈希超过 N 参数,它们都不允许您执行 mod 操作。
请,您会为我推荐什么解决方案,以便我可以存储这些非常长的数字+对它们使用 mod 操作。
谢谢
解决方案
你不能在 C++ 中存储这么大的数字,但只要 N 不是一个巨大的数字,它当然是可能的。诀窍是在% N
遍历字符串时执行,因此您的号码永远不会溢出。
你可以使用这个方法——https://math.stackexchange.com/a/453108找到(A^B)%N,即(31^200)%N。
//This is the algorithm mentioned in the above link
const size_t N = 1e9 + 7;
size_t bigPower(size_t x, size_t p) {
size_t ans = 1;
while(p > 0){
if(p % 2 == 1)
ans = (ans*x)%N;
x = (x*x)%N;
p /= 2;
}
return ans;
}
然后,按照公式不应该溢出数字。
size_t hashCode(const string& s) {
size_t result = 0;
for(size_t i = 0; i< s.size(); i++) {
result += (s[i] * bigPower(31, s.size()-1-i))%N;
result %= N;
}
return result;
}
更新 我发现 Java hashCode 实际上可以溢出并返回负散列码 - HashCode 给出负值。因此,如果您希望您的 hashCode 表现得像 Java,您不妨允许溢出。
//This might produce the exact same hashCode as Java.
int hashCode(const string& s) {
int result = 0;
for(int i = 0; i< s.size(); i++) {
int m = 1;
for(int j=0; j<s.size()-1-i; j++) {
m *= 31;
}
result += (s[i] * m);
}
return result;
}
推荐阅读
- c# - 通过 SendKey 将数据从 Web 应用程序推送到桌面应用程序
- .net - System.Transactions.TransactionScope 缺少函数“new()”
- javascript - 我找不到事件侦听器及其处理程序,但它存在
- azure - 天蓝色函数 - 当 eventthub 中的新事件时触发,将其写入 cosmos db - 不起作用,为什么?
- r - 从作为字符串的总和中获取结果
- amp-html - 与 AMP.setState 深度合并
- r - 有条件地在R中将列从一个数据帧合并到另一个数据帧
- javascript - 如何在 Unsplash API 中制作更多照片?
- powershell - 使用 Select-String 检查 powershell 中的两个 .txt 文件
- python - 数据准备中的 Python 与 Stata