2012-04-25 87 views
1

我有一個包含整數值的STL向量的STL向量。一些內部向量是重複的,但它們的元素順序不一樣。現在,我想獲得一個矢量矢量而不需要任何重複的內部矢量。我已經看到了下面的方法:刪除STL向量中的重複STL向量

std::vector<std::vector<int>> myVec; 
std::sort(myVec.begin(), myVec.end()); 
myVec.erase(std::unique(myVec.begin(), myVec.end()), myVec.end()); 

的問題是,我想eleminate重複保持每個順序的元素的順序(原始訂單或者不對它進行排序),什麼是做到這一點的最好辦法?有另一種方式更有效嗎?

例子:

1 6 4 5 
3 1 5 2----> result of elimination: 1 6 4 5 
2 1 3 5        3 1 5 2 

在此先感謝

vacing

+2

我不明白你的榜樣,但也許這只是我。 – 2012-04-25 01:42:02

+1

他在這個例子中顯示的是因爲'3 1 5 2'和'2 1 3 5'包含相同的值,只是不是相同的順序,他們被認爲是重複的,因此被刪除。 – 2012-04-25 02:02:07

+0

在這種情況下,發佈的方法是不正確的,因爲它不排序內部向量。 – devil 2012-04-25 02:06:54

回答

2

這個問題並不完全清楚。所以我會給出兩個答案。 (1)如果您希望刪除重複項但保留1份副本,同時保留myVec的順序,則需要使用一組。

std::vector< std::vector<int> > myVec; 
//or std::unordered_set if you expect mostly unique sorted inner vectors 
std::set< std::vector<int> > exists; 
std::vector< std::vector<int> > tmpVec; 

for (std::size_t i=0, N=myVec.size(); i<N; ++i) 
{ 
    std::vector<int> key(myVec[i]); 
    std::sort(key.begin(), key.end()); 
    if (exists.find(key) == exists.end()) 
    { 
     exists.insert(key); 
     tmpVec.push_back(std::vector<int>()); 
     std::swap(myVec[i], tmpVec.back()); 
    } 
} 

std::swap(tmpVec, myVec); 

(2)如果你想刪除出現不止一次在myVec你需要地圖櫃中的所有元素。

std::vector< std::vector<int> > myVec; 
//or std::unordered_map if you expect mostly unique sorted inner vectors 
std::map< std::vector<int>, unsigned > counters; 

// first loop to count 
for (std::size_t i=0, N=myVec.size(); i<N; ++i) 
{ 
    std::vector<int> key(myVec[i]); 
    std::sort(key.begin(), key.end()); 
    ++counters[key]; 
} 

// second loop to filter 
std::vector< std::vector<int> > tmpVec; 
for (std::size_t i=0, N=myVec.size(); i<N; ++i) 
{ 
    std::vector<int> key(myVec[i]); 
    std::sort(key.begin(), key.end()); 
    if (counters[key] == 1) 
    { 
     tmpVec.push_back(std::vector<int>()); 
     std::swap(myVec[i], tmpVec.back()); 
    } 
} 

std::swap(tmpVec, myVec); 

這兩種解決方案在尊重myVec元素的順序,並保留在所述內矢量元素的原始順序。這裏

+0

差不多,但從這個例子看來,海報似乎並不想包含任何有重複項目的項目(而你正在篩選出多餘的副本)。 – jamesdlin 2012-04-25 02:49:37

+0

我明白了,在這種情況下,我們需要一個計數器。將編輯。 – devil 2012-04-25 06:05:55

+0

非常感謝! – user1310873 2012-04-25 08:16:23

1

你可以做的是進入每個向量到這是在年代由載體和排序的值鍵控地圖列表然後通過地圖選擇矢量.size()爲1的地圖。

您的地圖將如下所示:

map<vector<int>, vector<vector<int> > > m; 

插入如下:

m[/*sorted inner_vector*/].push_back(inner_vector); 

注意,被推inner_vector保持其原始順序。

+0

對不起,我犯了一個錯誤,我編輯了這個例子。在這種情況下,魔鬼選項1對我有好處,謝謝。 – user1310873 2012-04-25 07:19:38

0

這人會提醒用戶,如果int載體中已經存在:

using namespace std; 
    int num, prev; 

    cout << "Number: "; cin >> num; 

      vec.push_back(num); 
      sort(vec.begin(), vec.end()); 
      for (size_t i = 0; i < vec.size()-1; ++i) 
      { 
       prev = vec[i]; 
       if (prev == num) 
       { 
        cout << "Duplicated\n"; // or whatever. 
        vec.erase(vec.begin() + i); // Delete the duplicated value. 
       } 
      }