将单词前5字母转为带字母表相对值的无符号整数作Trie键的问题
解决单词转Trie键的哈希函数问题
现有代码的问题
- 乘数计算逻辑错误:使用
pow进行浮点数运算,会引入精度误差,导致乘数计算不准确,最终拼接的数值完全偏离预期。 - 数值存储方式错误:未考虑字母对应值(0-25)需要两位十进制数存储,当值超过9时,会和前一位数值重叠,导致"溢出"混乱。
修正方案
核心思路是每个字母对应值占两位十进制数,通过整数运算依次拼接,避免浮点数误差和数值重叠。
直接计算版本
#include <ctype.h> unsigned int hash(const char *word) { unsigned int output = 0; for (int i = 0; i < 5; i++) { // 处理单词长度不足5的情况,补0 int val = 0; if (word[i] != '\0') { val = toupper(word[i]) - 'A'; // 过滤非字母字符,设为0 val = (val >= 0 && val <= 25) ? val : 0; } // 每次将当前结果左移两位十进制数,加上当前字母值 output = output * 100 + val; } return output; }
以"fabulous"为例,前5个字母F,A,B,U,L对应值5,0,1,20,11,计算过程:
- 第1步:
0*100 +5 =5 - 第2步:
5*100 +0=50 - 第3步:
50*100 +1=501 - 第4步:
501*100 +20=50120 - 第5步:
50120*100 +11=5012011
最终得到预期结果5012011。
数组存储后转换版本
如果先将字母值存入数组再转换,逻辑和直接计算一致:
#include <ctype.h> unsigned int hash(const char *word) { int values[5] = {0}; // 初始化默认补0 // 填充数组 for (int i = 0; i < 5 && word[i] != '\0'; i++) { int val = toupper(word[i]) - 'A'; values[i] = (val >=0 && val <=25) ? val : 0; } // 数组转无符号整数 unsigned int output = 0; for (int i = 0; i <5; i++) { output = output *100 + values[i]; } return output; }
关键要点
- 用
*100实现两位十进制数的拼接,确保每个字母值独立占位,不会重叠。 - 避免使用
pow等浮点数函数,改用纯整数运算保证精度。 - 增加边界处理:单词长度不足5时补0,非字母字符统一设为0,保证结果有效性。
内容的提问来源于stack exchange,提问作者Fede O.
相关产品推荐
相关产品推荐

