基数排序字符串数组

时间:2015-09-12 21:01:07

标签: c++ string

我正在尝试使用基数排序来对包含社会保障和出生日期的文件进行排序,格式如下所示" ### - ## - ####,#######。I必须根据命令行开关对每个字段应用基数排序。我有一个基数排序,适用于int数组,我试图修改字符串类型数组的代码,但我不知道如何实现这一点。我通过比较字符串和数据透视表对字符串类型进行了快速排序,但这对于基数排序工作正常我不是如果我可以用字符串类型执行此操作或者我必须将字符串转换为整数。我曾试图使用" atoi"转换为整数但我不知道如果必须如何正确地执行此操作。

   string getMax(string arr[], int n){
    string max = arr[0];
    for (int i = 1; i < n; i++){
        if (arr[i]>max)
            max = arr[i];
    }
    return max;
   }

   void countSort(string a[], int size, int k){
    string *b = NULL; int *c = NULL;
    b = new string[size];
    c = new int[k]; 



    for (int i = 0; i <k; i++){
        c[i] = 0;
        //cout << c[i] << "\n";
    }
    for (int j = 0; j <size; j++){   
        c[(a[j]/k)%10]++;            //a[j] is a string
        //cout << c[a[j]] << endl;
    }

    for (int f = 1; f <10; f++){
        c[f] += c[f - 1];
    }

    for (int r = size - 1; r >= 0; r--){
        b[c[(a[r] / k) % 10] - 1] = a[r];
        c[(a[r] / k) % 10]--;
    }

    for (int l = 0; l < size; l++){
        a[l] = b[l];
    }

    }


    void radixSort(string b[], int r){
    string max = getMax(b, r);
    for (int digit = 1; max / digit > 0; digit *= 10){
        countSort(b, r, digit);
    }

    };  

1 个答案:

答案 0 :(得分:2)

我没有尝试过,但我认为你可以为字符串做基数排序。

  1. 计算要排序的数组中最长字符串的长度。
  2. 对整数进行基数排序。使用字符串中的每个字符进行排序。 如果字符串比另一个字符串短并且&#34;数字&#34;中没有字符,请将其值视为-65536(或者比任何其他字符小的值)。
  3. 更新:我测试了我的想法,似乎有效。

    #include <cstdio>
    #include <string>
    using std::string;
    
    size_t getMax(string arr[], int n){
        size_t max = arr[0].size();
        for (int i = 1; i < n; i++){
            if (arr[i].size()>max)
                max = arr[i].size();
        }
        return max;
    }
    
    void countSort(string a[], int size, size_t k){
        string *b = NULL; int *c = NULL;
        b = new string[size];
        c = new int[257];
    
    
    
        for (int i = 0; i <257; i++){
            c[i] = 0;
            //cout << c[i] << "\n";
        }
        for (int j = 0; j <size; j++){   
            c[k < a[j].size() ? (int)(unsigned char)a[j][k] + 1 : 0]++;            //a[j] is a string
            //cout << c[a[j]] << endl;
        }
    
        for (int f = 1; f <257; f++){
            c[f] += c[f - 1];
        }
    
        for (int r = size - 1; r >= 0; r--){
            b[c[k < a[r].size() ? (int)(unsigned char)a[r][k] + 1 : 0] - 1] = a[r];
            c[k < a[r].size() ? (int)(unsigned char)a[r][k] + 1 : 0]--;
        }
    
        for (int l = 0; l < size; l++){
            a[l] = b[l];
        }
    
        // avold memory leak
        delete[] b;
        delete[] c;
    }
    
    
    void radixSort(string b[], int r){
        size_t max = getMax(b, r);
        for (size_t digit = max; digit > 0; digit--){ // size_t is unsigned, so avoid using digit >= 0, which is always true
            countSort(b, r, digit - 1);
        }
    
    }
    
    int main(void) {
        string data[] = {
            "aaaba",
            "dfjasdlifjai",
            "jiifjeogiejogp",
            "aabaaaa",
            "gsgj",
            "gerph",
            "aaaaaaa",
            "htjltjlrth",
            "joasdjfisdjfdo",
            "hthe",
            "aaaaaba",
            "jrykpjl",
            "hkoptjltp",
            "aaaaaa",
            "lprrjt"
        };
        puts("before sorting:");
        for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
            printf("    %s\n", data[i].c_str());
        }
        radixSort(data, (int)(sizeof(data) / sizeof(data[0])));
        puts("after sorting:");
        for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
            printf("    %s\n", data[i].c_str());
        }
        return 0;
    }