在保留绝对值的同时将char转换为unsigned int

tjvv9vkg  于 2022-12-29  发布在  其他
关注(0)|答案(3)|浏览(175)

所以我需要把单词的前5个字母转换成一个无符号的整型,保持它们在字母表中的相对值,比如“fabriculous”变成了5 0 1 20 11或者5012011这样就可以把它作为一个trie的键.
现在我有:

unsigned int hash(const char *word)
{
    unsigned int output = 0;

    for(int i = 0; i < 5; i++)
    {
        int multiplier = 10000;
        if (i > 0)
        {
            multiplier = 10000 / (i * pow(10.0, i-1) / i);
        }
        output += (toupper(word[i]) - 'A') * multiplier;
    }
    return output;
}

现在它输出50311,它是所有整数的正确和 * 它们各自的位置(5 * 10,000表示位于5的第一位,以此类推)但任何大于10的数字都会“渗透”前一个值,因此20(即U)会渗透并影响b,11会影响20的最后一位数字,但同样的情况也会发生在J后面的每个字母上。
我也想过把每个值加到一个数组中,所以output[0] = 5,等等,但是我需要把数组转换成一个unsigned int来返回它,并且不知道如何去做。

afdcj2ne

afdcj2ne1#

让每个字符在结果中使用2个数字,这样每个字母的数字之间就不会有任何重叠。使用100的幂而不是10来执行此操作。示例的结果将是500012011

#define LIMIT 5

unsigned int hash(const char *word)
{
    unsigned int output = 0;
    size_t len = strlen(word);
    int max = len < LIMIT ? len : LIMIT;
    unsigned int multiplier = 100000000;
    for(int i = 0; i < max; i++)
    {
        output += (toupper(word[i]) - 'A') * multiplier;
        multiplier /= 100;
    }
    return output;
}
lstz6jyr

lstz6jyr2#

OP:“......但是我需要把数组转换成一个unsigned int来返回它,但是我不知道怎么做。
这并不难。通过一些位屏蔽(低阶5位)和移位(20,15,10,5,0),可以快速组合一个整数值。5x 5 =25位,因此32位中的“有符号/无符号”是无关紧要的。

uint32_t hash( const char *word ) {
    const int LTRS_USED = 5;

    uint32_t val = 0;
    int shft = LTRS_USED * 5;
    for( size_t c = 0; c < LTRS_USED && word[c]; c++ )
        val |= (word[c] & 037) << (shft -= 5); // see disclaimer below

    return val;
}

int main() {
    const char *words[] = {
        "The", "quick", "brown", "fox", "jumps", "jumped", "over", "a", "lazy", "dog"
    };
    const size_t nw = sizeof words/sizeof words[0];

    for( size_t i = 0; i < nw; i++ )
        printf( "%10d %s\n", hash( words[i] ), words[i] );

    return 0;
}

注意下面的值(特别是“jumps/jumps”)表明整数值表示实现了一个“sorted”散列序列(如果'e'Map为17,'s'将为31,这是有效的)。

21238784 The
  18523243 quick
   2703086 brown
   6807552 fox
  11187731 jumps
  11187717 jumped
  16455232 over
   1048576 a
  12643104 lazy
   4692992 dog

可以尝试使用4个或6个字母,看看这对速度和音量要求有何影响。

**(免责声明:这个答案假定所有字符都是7位ASCII码,其他字符集需要其他解决方案。)

tyg4sfes

tyg4sfes3#

multiplier存在错误
试试这个:

unsigned int hash(const char *word)
{
    unsigned int output = 0;

    for(int i = 0; i < 5; i++)
    {
        int charVal = toupper(word[i]) - 'A';
        if (charVal > 9)
        {
            output = output * 100 + charVal;
        }
        else
        {
            output = output * 10 + charVal;
        }
    }
    return output;
}

相关问题