从 int 获取单个数字以在 C/C++ 中进行基数排序的最佳方法

Posted

技术标签:

【中文标题】从 int 获取单个数字以在 C/C++ 中进行基数排序的最佳方法【英文标题】:Best way to get individual digits from int for radix sort in C/C++ 【发布时间】:2010-05-24 02:06:57 【问题描述】:

从具有 n 个数字的 int 中获取单个数字以用于基数排序算法的最佳方法是什么?我想知道在 C/C++ 中是否有特别好的方法,如果没有,一般的最佳解决方案是什么?

编辑:澄清一下,我一直在寻找解决方案,而不是将其转换为字符串并将其视为数字数组。

【问题讨论】:

【参考方案1】:

使用大小为2^k 的数字。提取nth 数字:

#define BASE (2<<k)
#define MASK (BASE-1)

inline unsigned get_digit(unsigned word, int n) 
    return (word >> (n*k)) & MASK;

使用移位和掩码(通过 base 为 2 的幂)避免了昂贵的整数除法指令。

之后,选择最佳基础是一个实验性问题(特定硬件的时间/空间权衡)。可能k==3 (base 8) 效果很好并且限制了桶的数量,但是k==4 (base 16) 看起来更有吸引力,因为它划分了字长。但是,不分字长的基数确实没有什么问题,您可能会发现基数 32 或基数 64 的性能更好。这是一个实验性问题,可能会因硬件而异,具体取决于缓存的行为方式以及数组中有多少元素。

最后一点:如果您要对 signed 整数进行排序,生活会更加痛苦,因为您希望将最高有效位视为有符号。我建议将所有内容都视为未签名,然后如果您真的需要签名,则在基数排序的最后一步中,您将交换存储桶,以便最重要 1 的存储桶位于最重要 0 之前。这个问题是 如果k 划分字长,肯定会更容易

【讨论】:

【参考方案2】:

不要使用基数 10,使用基数 16。

for (int i = 0; i < 8; i++) 
    printf("%d\n", (n >> (i*4)) & 0xf);

由于整数在内部以二进制形式存储,这将比除以 10 来确定 十进制 位更有效。

【讨论】:

很好的回应,我选择了诺曼,因为他的回答更深入。

以上是关于从 int 获取单个数字以在 C/C++ 中进行基数排序的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

从输入中获取数字的最佳方法?

c# 将从单个文本框中获取的多个值分配给标签

C/C++ - sem_t 类型的单个信号量按顺序打印数字

⭐C/C++の深入浅出⭐int数与多枚举值互转

⭐C/C++の深入浅出⭐int数与多枚举值互转

如何在 VIEW 中获取单个字段以在 WHERE 中使用