尝试将哈希函数转换为 C
Trying to convert hash function to C
我看到了这个散列函数,想将它转换成 C。 .substring 和 toCharArray() 有问题
long sfold(String s, int M)
{
int intLength = s.length() / 4;
long sum = 0;
for (int j = 0; j < intLength; j++)
{
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++)
{
sum += c[k] * mult;
mult *= 256;
}
}
char c[] = s.substring(intLength * 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++)
{
sum += c[k] * mult;
mult *= 256;
}
return(Math.abs(sum) % M);
}
我做了以下更改:
long sfold(char* s, int M)
{
int intLength = strlen(s) / 4;
long sum = 0;
for (int j = 0; j < intLength; j++)
{
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
long mult = 1;
for (int k = 0; k < strlen(c); k++)
{
sum += c[k] * mult;
mult *= 256;
}
}
char c[] = s.substring(intLength * 4).toCharArray();
long mult = 1;
for (int k = 0; k < strlen(c); k++)
{
sum += c[k] * mult;
mult *= 256;
}
return(Math.abs(sum) % M);
}
这是我遇到问题的两行:
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
char c[] = s.substring(intLength * 4).toCharArray();
有人能解释一下这两行的作用吗?
第一个是每次将四个字符的块读取到数组中:
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
您可以将其替换为:
char c[4];
memcpy(c, s + 4*j, 4);
第二个是复制字符串的其余部分,从小于strlen(s)
的4的最大倍数到最后,因为:
int intLength = strlen(s) / 4;
因此:
char c[] = s.substring(intLength * 4).toCharArray();
只是:
char c[strlen(s)];
memcpy(c, s + intLength*4, strlen(s) - 4*intLength);
此时,你应该预先计算strlen(s)
并将其存储在一个变量中,因为C中的字符串实际上并不存在(它们只是char
的数组,其最后一个元素是[=19 =]
) 并且每次调用 strlen
意味着必须扫描整个字符串以获得 [=19=]
,以确定长度。
但是,所有这些副本甚至都不是必需的,因为您没有修改 s
,所以您只需调整循环中的索引,您就可以完全跳过 memcpy
:
long sfold(const char* s, size_t length, long M) {
size_t intLength = length / 4;
long sum = 0;
for (size_t j = 0; j < intLength; j++) {
long mult = 1;
for (int k = 0; k < 4; k++) {
sum += s[j*4 + k] * mult;
mult *= 256;
}
}
long mult = 1;
for (size_t k = intLength*4; k < length; k++) {
sum += s[k] * mult;
mult *= 256;
}
return labs(sum) % M;
}
我看到了这个散列函数,想将它转换成 C。 .substring 和 toCharArray() 有问题
long sfold(String s, int M)
{
int intLength = s.length() / 4;
long sum = 0;
for (int j = 0; j < intLength; j++)
{
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++)
{
sum += c[k] * mult;
mult *= 256;
}
}
char c[] = s.substring(intLength * 4).toCharArray();
long mult = 1;
for (int k = 0; k < c.length; k++)
{
sum += c[k] * mult;
mult *= 256;
}
return(Math.abs(sum) % M);
}
我做了以下更改:
long sfold(char* s, int M)
{
int intLength = strlen(s) / 4;
long sum = 0;
for (int j = 0; j < intLength; j++)
{
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
long mult = 1;
for (int k = 0; k < strlen(c); k++)
{
sum += c[k] * mult;
mult *= 256;
}
}
char c[] = s.substring(intLength * 4).toCharArray();
long mult = 1;
for (int k = 0; k < strlen(c); k++)
{
sum += c[k] * mult;
mult *= 256;
}
return(Math.abs(sum) % M);
}
这是我遇到问题的两行:
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
char c[] = s.substring(intLength * 4).toCharArray();
有人能解释一下这两行的作用吗?
第一个是每次将四个字符的块读取到数组中:
char c[] = s.substring(j * 4, (j * 4) + 4).toCharArray();
您可以将其替换为:
char c[4];
memcpy(c, s + 4*j, 4);
第二个是复制字符串的其余部分,从小于strlen(s)
的4的最大倍数到最后,因为:
int intLength = strlen(s) / 4;
因此:
char c[] = s.substring(intLength * 4).toCharArray();
只是:
char c[strlen(s)];
memcpy(c, s + intLength*4, strlen(s) - 4*intLength);
此时,你应该预先计算strlen(s)
并将其存储在一个变量中,因为C中的字符串实际上并不存在(它们只是char
的数组,其最后一个元素是[=19 =]
) 并且每次调用 strlen
意味着必须扫描整个字符串以获得 [=19=]
,以确定长度。
但是,所有这些副本甚至都不是必需的,因为您没有修改 s
,所以您只需调整循环中的索引,您就可以完全跳过 memcpy
:
long sfold(const char* s, size_t length, long M) {
size_t intLength = length / 4;
long sum = 0;
for (size_t j = 0; j < intLength; j++) {
long mult = 1;
for (int k = 0; k < 4; k++) {
sum += s[j*4 + k] * mult;
mult *= 256;
}
}
long mult = 1;
for (size_t k = intLength*4; k < length; k++) {
sum += s[k] * mult;
mult *= 256;
}
return labs(sum) % M;
}