簡體   English   中英

排序char *數組

[英]sorting char* arrays

我有一個數據結構

struct record {
    char cont[bufferSize];
    record *next;
};

當我向該結構添加新記錄時,我希望它們按字母順序排序。 我做了這個功能,在鏈接列表的正確位置(按字母)添加了記錄:

record *start=NULL, *p, *x;

void recAdd(char*temp) {
        p = new record;
        temp[strlen(temp)] = '\0';
        for (int j=0;j<bufferSize;j++) p->cont[j] = temp[j];
        if (start==NULL) start=p;
        else {
            x=start;
            int c=0;
            while (recComp(x->cont,p->cont) <= 0 && x->next != NULL) {
                    x=x->next;
                    c++;
            }
            if (c == 0) {
                p->next=start;
                start=p;
            }
            else {
                x=start;
                for (int i=0;i<c;i++) x=x->next;
                p->next=x->next;
                x->next=p;
            }
        }
        for (int j=0;j<bufferSize;j++) temp[j] = NULL;
    };

但是以某種方式不能正確解決問題。 我的功能出了什么問題?

也許我沒有回答您的問題,但是為什么不使用STL? 它將為您進行分類; 這些天,您不必編寫這樣的排序例程。

您的代碼一團糟。 語義和邏輯上都有許多問題,但是從根本上說,決定在哪里插入新節點的邏輯最有缺陷。 將其更改為此(在else塊中注意我的新代碼):

void recAdd(const char*t) {
        char temp[bufferSize];
        strcpy(temp, t);
        p = new record;
        temp[strlen(temp)] = '\0';
        for (int j=0;j<bufferSize;j++) p->cont[j] = temp[j];
        if (start==NULL) { start=p; start->next = 0; }
        else {
            record* x = start;
            record* prev = 0;
            while( x && recComp(x->cont, p->cont) <= 0 )
            {
                prev = x;
                x = x->next;
            }

            // p is a new node. p, x and prev are arranged thusly:
            // prev -> p -> x
            // if prev is null, p is a new head
            // if x is null, p is a new tail
            // otherwise, p is inserted between prev and x

            if( !prev )
            {
                p->next = start;
                start = p;
            }
            else if( !x )   
            // note this block and the next one could be combined.  
            // done this way for clarity.
            {
                prev->next = p;
                p->next = 0;
            }
            else
            {
                p->next = x;
                prev->next = p;
            }
        }
        for (int j=0;j<bufferSize;j++) temp[j] = NULL;
    };

但是事實是您很難編寫此代碼,因此您會要求SO進行修復,這一事實說明了一個重要的觀點:最好的代碼是您不必編寫的代碼。 您已經編寫了鏈表類型結構(可能是裸露的骨頭)和排序算法。 兩者都有缺陷,並且都具有工作,經過測試和有效的版本,它們是標准C ++庫的一部分。 您應該使用它們。 使用字符串而不是char * s。 使用向量而不是鏈接列表。 使用sort代替您的手動滾動排序算法。 總而言之,您的所有代碼都可以替換為:

vector<string> records;

// this for block just populates the vector with random strings
for( int i = 0; i < 10; ++i )
{
    string s;
    for( int j = 0, jx = 3+(rand()/(RAND_MAX/10)); j < jx; ++j )
        s += 'A'-1+(rand()/(RAND_MAX/26));
    cout << s << endl;
    records.push_back(s);
}

sort(records.begin(), records.end());
copy( records.begin(), records.end(), ostream_iterator<string>(cout, " "));

當您可以使用已經可用並且可以做自己想做的工具時,為什么還要手動滾動一堆東西並使自己面臨無數缺陷?

一些技巧:

  • 使用strcmp比較字符串
  • 更喜歡在結構體內部使用char指針。 這使您可以盲目分配它們而不進行復制,也不會浪費struct內部的空間
  • 如果您真的需要復制它們,請使用strdup分配新字符串
  • 跟蹤兩個當前元素,而不是一個,這將避免計算到目前為止您有多少個元素,並在找到正確位置時瀏覽列表兩次

如果使用STL向量實現簡單的插入排序(向量具有成員“插入”),則可以使您的生活更加輕松。

該代碼也將看起來更加干凈:)

查找cplusplus.com上的示例,您會發現它很有幫助。

正如其他人已經建議的那樣,STL使生活變得更加輕松。 似乎您所需要的只是一個經過排序的字符串容器:

#include <iostream>
#include <set>
#include <string>

int main()
{
    std::set<std::string> words;
    words.insert("hello");
    words.insert("beautiful");
    words.insert("world");

    for (std::set<std::string>::const_iterator it = words.begin(); it != words.end(); ++it)
    {
        std::cout << *it << std::endl;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM