2013-09-24 161 views
3

我是向量的向量,每個向量表示一個集合(在數學意義上)。例如:如何過濾相對於其他元素的矢量元素?

{{1, 3}, {4, 9, 14}, {1, 3}, {1, 4, 8, 9, 10, 14, 16}, {1, 3, 9}, {4, 9, 17, 22}} 

我想使能夠過濾的最有效的C++函數可能(在適當位置,如果可能的話)的載體,以便除去包含其他的每個項目。

例如,這裏:

  • {1, 3}{1, 3}包含和{1, 3, 9}
  • {4, 9, 14}{1, 4, 8, 9, 10, 14, 16}

包含然後將得到的矢量將是:

{{1, 3}, {4, 9, 14}, {4, 9, 17, 22}} 

因爲我從C++開始,並不知道如何有效地做到這一點。我在這裏的其他答案中發現了擦除/刪除習慣用法,除了通過擦除閉包作爲謂詞外,這在這裏似乎不太合適。這在C++中看起來不太習慣。

請注意,保持原始順序無關緊要,也不會影響每組中的值的排序。

+2

如果你保持每個向量的排序順序,那麼你應該能夠相當有效地做到這一點。 –

+1

{1,3,9}或{1,3,18}? –

+0

'{1,3,9}',對不起。 – Pierre

回答

1

鑑於我學會爲止,感謝您的非常有益的意見,我想出瞭解決的辦法是:

struct std::vector<size_t> colset; 

bool less_colsets(const colset& a, const colset& b) { 
    return a.size() < b.size(); 
} 

void sort_colsets(std::list<colset>& l) { 
    l.sort(less_colsets); 
} 

void strip_subsets(std::list<colset>& l) { 
    sort_colsets(l); 
    for (std::list<colset>::iterator i = l.begin(); i != l.end(); ++i) { 
    std::list<colset>::iterator j = next(i, 1); 
    while (j != l.end()) { 
     if (includes((*j).begin(), (*j).end(), (*i).begin(), (*i).end())) { 
     j = l.erase(j); 
     } 
     else { 
     ++j; 
     } 
    } 
    } 
} 

請注意,我用std::list這是更爲優化取代了最std::vector元素去除的地方。

這似乎按預期工作,但我需要一些更多的測試來證明這一點。 下一步將使用比includes更高效的比較功能,該功能將考慮到每個矢量都是詞法排序(程序保證)的事實。我明天會試試這個。

編輯:看起來像std::includes已經照顧了這個事實。好極了!

謝謝大家。

+0

'std :: includes'要求對兩個範圍進行排序,並使用此屬性。其複雜性在兩個範圍的總長度上是線性的。 –

+0

我沒有看到那個屬性......似乎比我想象的還要好。大! – Pierre