2013-03-26 78 views
3

根據結構向量中所有結構的每個向量中的第一個單詞按字母順序排列結構向量的最佳方法是什麼?如何根據要分類的向量內的向量<string>對結構向量進行排序?

struct sentence{ 
    vector<string> words; 
}; 

vector<sentence> allSentences; 

換句話說,如何根據單詞[0]對所有句子進行排序?


編輯:我用以下解決方案:

bool cmp(const sentence& lhs, const sentence & rhs) 
{ 
    return lhs.words[0] < rhs.words[0]; 
} 

std::sort(allSentences.begin(), allSentences.end(), cmp); 
+0

感謝您的偉大的答案。也許有人可以解釋爲什麼這不起作用:return lhs.wordCombinated [0] .compare(rhs.wordCombinated [0]); – gkraft 2013-03-27 08:40:18

回答

6

提供合適的比較二進制函數並將其傳遞給std::sort。例如

bool cmp(const sentence& lhs, const sentence & rhs) 
{ 
    return lhs.words[0] < rhs.words[0]; 
} 

然後

std::sort(allSentences.begin(), allSentences.end(), cmp); 

替代地,在C++ 11可以使用lambda匿名函數

std::sort(allSentences.begin(), allSentences.end(), 
      [](const sentence& lhs, const sentence & rhs) { 
        return lhs.words[0] < rhs.words[0];} 
     ); 
3

你需要一些比較函數,你可以傳遞給std::sort

bool compare(const sentence& a, const sentence& b) 
{ 
    return a.words[0] < b.words[0]; 
} 

正如你所看到的,它需要兩個sentences,如果第一個sentence的第一個單詞「小於」第一個單詞的話,則返回true cond sentence

然後你就可以很容易進行排序allSentences

std::sort(allSentences.begin(), allSentences.end(), compare); 

當然,採用這種比較意味着像{"hello", "world"}{"hello", "friend"}句子會比較平等的。但這就是你要求的。

3

一般而言,有三種不同類型的場景進行比較實現你應該考慮。

  1. 你的對象,使總是意義上的比較。它與您想要比較對象的場景無關。然後:爲您的班級實施operator<。只要比較兩個對象(使用標準算法的<),就可以使用此運算符。 (對於單個場景,您仍然可以使用下面的其他方法「覆蓋」此行爲)。

    爲此,具有以下功能擴展您的類:

    struct sentence{ 
        vector<string> words; 
        bool operator<(const sentence &other) const { 
         return this->words[0] < other.words[0]; 
        } 
    }; 
    

    然後,只需撥打句子的向量的標準排序算法沒有其他參數:

    std::sort(allSentences.begin(), allSentences.end()); 
    

    但是,您的方案聽起來不像這是最好的方法,因爲通過第一個詞比較是你不想要的東西總是,也許只有一種情況。

  2. 將用於只有一次你的對象的比較。在C++ 11中,你有lambda函數(匿名的,字面上的內聯函數),它可以直接傳遞給將要使用它的算法函數,如std::sort。這是我最喜歡的解決方案:

    // Sort lexicographical by first word 
    std::sort(allSentences.begin(), allSentences.end(), 
          [](const sentence& a, const sentence& b) { 
        a.words[0] < b.words[0]; 
    }); 
    

    在C++ 03,在那裏你沒有lambda表達式,使用3號方案:

  3. 一套不同,可重複使用的比較方法,也許是參數化比較功能。例子是:比較第一個單詞,比較長度,比較其他東西...在這種情況下,比較函數可以作爲獨立函數並使用函數指針,或者作爲函數實現它們(它可以被參數化)。另外,在這種情況下,存儲在變量中的lambda表達式可以完成這項工作

    這種方法的優點是名稱的比較方法,給他們一個含義。如果您使用的同一對象的不同比較,但重新使用它們,這是一個巨大的優勢:

    // Lexicographical comparison by the first word only 
    bool compareLexByFirstWord(const sentence& a, const sentence& b) { 
        return a.words[0] < b.words[0]; 
    } 
    
    // Lexicographical comparison by all words 
    bool compareLex(const sentence& a, const sentence& b) { 
        return a.words < b.words; 
    } 
    
    // Decide which behavior to use when actually using the comparison: 
    std::sort(sentence.begin(), sentence.end(), compareLexByFirstWord); 
    std::sort(sentence.begin(), sentence.end(), compareLex); 
    
+0

感謝您的提示#1! – gkraft 2013-03-27 08:25:01

+0

很有幫助。同上......感謝您的提示 – Fractal 2014-08-17 20:57:19