2015-11-08 78 views
0

我已經聲明如下的結構:集存儲混亂

struct data{ 
    vector<string> att; 
    string ds; 
}; 

現在一組來自多個數據元素根據不同vector<string> attstring ds

set<data> s; 

如何存儲唯一的數據做這個?

+0

您需要某種方式來比較'data'元素。你可以通過覆蓋'operator <'或者提供一個[自定義'Compare'函數來'set'作爲第二個模板參數](http://en.cppreference.com/w/cpp/container/set)。 – Cornstalks

+0

[C++ set容器問題]的可能重複(http://stackoverflow.com/questions/14784620/problems-with-c-set-container) – Cornstalks

+0

@Cornstalks你能否提供這個特例的比較函數的代碼? – sb15

回答

0

注意:你可以閱讀更多關於我用比較的東西(std::tiein Implementing comparison operators via 'tuple' and 'tie', a good idea?

std::stringstd::vector的伎倆已經有operator<定義:for stringsfor vectors。因此,我們可以使用它們與std::tie創建一個臨時的std::tuple(它只是使用對數據成員的引用,它不創建任何副本,因此它是有效的)進行比較。


選項1:提供operator<

std::set需要比較的對象,所以它知道什麼是獨特的,如何理清。它會默認使用operator<(通過std::less),所以如果你爲你的課程提供該操作符,它將使用它。像這樣:

struct data{ 
    vector<string> att; 
    string ds; 

    operator<(const data& other) { 
     // Be sure to #include <tuple> for std::tie 
     return std::tie(att, ds) < std::tie(other.att, ds); 

     // If you don't want to (or can't) use std::tie, you can do this: 
     // return att < other.att || (att == other.att && ds < other.ds); 
    } 
}; 
std::set<data> my_set; // Now it works. 

選項2:提供一個仿函數

這將使用Comparefunctor比較兩個data對象(而不是operator<,所以我們並不需要定義它):

struct Compare { 
    bool operator()(const data& left, const data& right) const { 
     return std::tie(left.att, left.ds) < std::tie(right.att, right.ds); 

     // Again, if you don't want to (or can't) use std::tie, you can do this: 
     // return left.att < right.att || (left.att == right.att && left.ds < right.ds); 
    } 
}; 
std::set<data, Compare> my_set; // Now it works. 
2

不知道你是如何想你的結構要比較什麼,你可以嘗試以下方法:

struct data 
{ 
    vector<string> att; 
    string ds; 

    friend bool operator < (const data& lhs, const data& rhs) 
    { 
     if (std::lexicographical_compare(lhs.att.begin(), lhs.att.end(), rhs.att.begin(), rhs.att.end())) 
     { 
      return true; 
     } 
     else if (std::lexicographical_compare(rhs.att.begin(), rhs.att.end(), lhs.att.begin(), lhs.att.end())) 
     { 
      return false; 
     } 
     else 
     { 
      return lhs.ds < rhs.ds; 
     } 
    } 
}; 

我不滿意這個解決方案,因爲它執行兩次逐一比較,這是低效的。希望有人會提出更好的解決方案。

基本的想法是,對於每個成員,比較左<的權利。如果爲true,則返回true,否則比較右邊的<。如果爲true,則返回false。否則,繼續下一個成員。

+0

@Cornstalks我不知道。這會弄清楚如何比較載體?這是否會製作矢量的副本? –