如何使用基数排序对变长字符串数组进行排序?

Posted

技术标签:

【中文标题】如何使用基数排序对变长字符串数组进行排序?【英文标题】:How to sort a variable-length string array with radix sort? 【发布时间】:2015-06-12 03:08:29 【问题描述】:

我知道基数排序可以对相同长度的字符串数组进行排序,但是是否可以对变长字符串进行排序。如果是,实现此功能的 C 系列代码或伪代码是什么?

对于可变长度的字符串,它可能不是一个快速的算法,但它很容易实现基数排序,因此如果需要快速编码排序,它会很有用。

【问题讨论】:

【参考方案1】:

我不太清楚您所说的“可变长度字符串”是什么意思,但您可以就地执行二进制 MSB 基数排序,因此字符串的长度无关紧要,因为没有中间存储桶。

#include <stdio.h>
#include <algorithm>

static void display(char *str, int *data, int size)

    printf("%s: ", str);

    for(int v=0;v<size;v++) 
        printf("%d ", data[v]);
    

    printf("\n");


static void sort(int *data, int size, int bit)

    if (bit == 0)
        return;

    int b = 0;
    int e = size;

    if (size > 0) 
        while (b != e) 
            if (data[b] & (1 << bit)) 
                std::swap(data[b], data[--e]);
            
            else 
                b++;
            
        

        sort(data, e, bit - 1);
        sort(data + b, size - b, bit - 1);
    


int main()

    int data[] =  13, 12, 22, 20, 3, 4, 14, 92, 11 ;
    int size = sizeof(data) / sizeof(data[0]);

    display("Before", data, size);
    sort(data, size, sizeof(int)*8 - 1);
    display("After", data, size);

【讨论】:

具有不同长度的字符串;长度不尽相同;每个字符串的字符数不同。为了给出问题的上下文,想象对一个 1 GB 的文件进行排序,每行带有 Stringchar*(您可以假设 '\n' 行结尾)。赞成尝试,但这里排序的是int 的数组,因此如果您可以修改代码以对字符串进行排序,那可能会回答我的问题。【参考方案2】:

您可以对可变长度字符串进行 MSB 优先基数排序。 有几个不明显的细节:

通过 #N 将根据 strvec[i][N] 将输入向量中的字符串划分(分散)为 256 个分区。然后它将按顺序扫描分区,并将(重新插入)字符串放回输入向量中。

现在稍微复杂一点...

当你到达一个字符串的末尾时,它就处于它的最终位置,永远不要再被触摸。这会将之前和之后的字符串拆分为单独的范围。每次传递的结果是一组尚未排序的行的范围。

这意味着传递#N,在第一个之后,扫描每个范围中的字符串,并将源范围ID(索引)与字符串一起存储在分区中。在“重新插入”步骤中,它将字符串放回其源范围;再次,它生成一组新的未排序行范围。

如果您向前扫描输入范围,然后向后扫描分区并从每个源范围的后面重新插入,您将保持基数排序的稳定排序优势。

您也可以使用递归(从头开始对任何子范围进行完整排序),但上述方法可以节省设置时间并且速度更快。

还有更多细节......快速排序适用于对小范围(例如,最多 16 个)进行插入排序;基数排序受益于做同样的事情。 可以使用多个字节作为分区索引。一种方法是:Radix Sort-Mischa Sandberg-2010 还有其他方法。 抱歉,我无法发布代码;它现在是专有的。

【讨论】:

以上是关于如何使用基数排序对变长字符串数组进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

C++:使用 LSD 基数排序对字符串进行排序崩溃

后缀排序

如何使用分布排序(基数排序等)对字符串进行排序?

基数排序是不是用于后缀排序?

桶排序——基数排序

如何对包含多个字符串的结构应用基数排序(使用计数排序)