Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 哈希字符串更改大小写_C++_C++17 - Fatal编程技术网

C++ 哈希字符串更改大小写

C++ 哈希字符串更改大小写,c++,c++17,C++,C++17,我有一个constexpr散列字符串函数,它在编译时被调用 我想知道,如何在对字符串进行散列之前将其转换为大写或小写 constexpr unsigned long long int HashString(const char* str, unsigned long long int hash = 0) { return (*str == 0) ? hash : 101 * HashString(str + 1) + *str; } 如果我正确理解您的目标,这是可能的,但需要注意以下几

我有一个constexpr散列字符串函数,它在编译时被调用

我想知道,如何在对字符串进行散列之前将其转换为大写或小写

constexpr unsigned long long int HashString(const char* str, unsigned long long int hash = 0)
{
    return (*str == 0) ? hash : 101 * HashString(str + 1) + *str;
}

如果我正确理解您的目标,这是可能的,但需要注意以下几点:

实际上,您不能在constexpr函数中构建新的字符串文字。这种能力在C++中不存在,因此在编译时将字符串转换为小写是不可能的,至少在特定的方式中是不可能的。 此处给出的答案假设输入为ASCII;例如,对于非ASCII字符串UTF-8,它要么不会改变多字节字符的大小写,要么甚至可能损坏多字节字符,从而导致UTF-8解码器在解码字符串时失败。 因为我们不能从constexpr函数中返回新的字符串文字,所以我们需要能够为哈希函数提供一个映射函数来应用于每个字符。例如,下面是一个constexpr映射函数,用于将ASCII字符转换为小写:

constexpr char ascii_tolower(char v) {
    return v >= 'A' && v <= 'Z' ?
        v + ('a' - 'A') :
        v;
}
现在,我们可以在constexpr上下文中使用此函数和任意映射函数,如下所示:

constexpr int hash_a = hash_fn<ascii_tolower>("FoObAr");
constexpr int hash_b = hash_fn<ascii_tolower>("fOoBaR");


请注意,此哈希函数非常简单,很容易产生冲突。它不是一个好的哈希函数的示例,只是一个使用constexpr函数作为模板参数的技术示例。

如果字符串仅包含字母字符,只需根据需要将第二个*str更改为toupper*str或tolower*str即可。否则,您将不得不对*str执行更复杂的操作,作为读者的练习。标准toupper和tolower函数本身不是constexpr,因此不能在constexpr函数内调用它们,对吗?。不过,编写自己的constexpr版本会很容易。@RemyLebeau如果需要支持UTF-8、区域设置、文件编码,可能不会那么容易……这个哈希函数会产生冲突是什么意思?@yino我的意思是哈希函数是一个坏的哈希函数。只有字符串中的最后11个字符才有意义;对于长字符串,如果最后11个字符相同,则哈希值将相同-这对于哈希函数是允许的,但不是最佳的。我建议在递归调用的范例中使用更好的哈希函数。这里的hash_fn只是演示获取constexpr函数模板参数并递归计算hash的技术。
template <constexpr char (*fn)(char) = identity>
constexpr int hash_fn(char const *str) {
    return *str ? fn(*str) ^ (hash_fn<fn>(str + 1) << 3) : 0;
}
constexpr int hash_a = hash_fn<ascii_tolower>("FoObAr");
constexpr int hash_b = hash_fn<ascii_tolower>("fOoBaR");