2013-10-08 41 views
0

我有串的名單,我怎麼能在一個std ::列表中刪除重複的值,如刪除在一個std重複項目::名單

std::list<std::string> listName; 

listName.push_back("Foo"); 
listName.push_back("Bar"); 
listName.push_back("Foo"); 

然後我想刪除重複的名字,其是「Foo」。剩下的只是「酒吧」的名字。

謝謝!

+1

@DyP:該OP希望除去重複項的所有實例(即如果「foo」出現兩次,ALL「foo」將被刪除,'list :: unique()'不會這樣做) –

+0

@JonathanPotter哦!良好的漁獲 – dyp

回答

2

如果你只想在listName獨特的元素,你可以這樣做:

listName.sort(); 
listName.unique(); 

LISTNAME仍應:"Foo", "Bar"

如果你想擺脫所有的元素都重複的,你可以使用std::list::sort排序元素,然後使用std::adjacent_find查找重複的元素。

listName.sort(); 

std::list<std::string>::iterator ab = std::adjacent_find(listName.begin(), listName.end()); 
if (ab != listName.end()) // if duplicate elements are found 
{ 
    std::list<std::string>::iterator ae = std::upper_bound(listName.begin(), listName.end(), *ab); // try to locate last occurrence 
    if (std::distance(ab, ae) > 1) 
    { 
        listName.erase(ab, ae); // remove all dup elements 
    } 
} 

LISTNAME仍然存在:"Bar"

here脫穎而出更std::list inerface你能做到這一點

+0

OP表示只剩下「Bar」。這也會有「Foo」。 –

+0

我只是做了這種做法,它是錯誤的,因爲OP要'而剩下的只是「酒吧」的名字。' – billz

+0

人們需要仔細閱讀這個問題,並停止推薦'list :: unique()':) –

0

的一種方法是使用std::map代替list。地圖將存儲字符串並保存它們出現次數。您的代碼唯一真正的變化是您需要使用++而不是push_back將字符串放在地圖中;

std::map<std::string, int> listName; 
++listName["Foo"]; 
++listName["Bar"]; 
++listName["Foo"]; 

然後用大於1的計數中刪除條目:

for (auto it = listName.begin(); it != listName.end();) 
{ 
    if (it->second > 1) 
     listName.erase(it++); 
    else 
     ++it; 
} 
0

排序列表,那麼你可以很容易地找到重複的。

#include <list> 
#include <iostream> 
#include <algorithm> 

int main() 
{ 
    std::list<std::string> listName = {"Foo", "Bar", "Foo", "Foobar"}; 

    listName.sort(); 

    for(auto i = listName.begin(); i != listName.end();) 
    { 
     auto range = std::equal_range(i, listName.end(), *i); 

     if(std::next(range.first) != range.second) 
      i = listName.erase(range.first, range.second); 
     else ++i; 
    } 

    for(auto const& e : listName) std::cout << e << ", "; 
} 

最短的版本,我可以想出,但兩次迭代在每個元素被刪除(一次equal_range,一旦在erase)。

可替換地,一旦迭代在每個元素:

listName.sort(); 

    for(auto i = listName.begin(); i != listName.end();) 
    { 
     auto j = std::next(i); 
     bool duplicate = false; 

     while(j != listName.end() && *j == *i) 
     { 
      duplicate = true; 
      j = listName.erase(j); 
     } 

     if(duplicate) i = listName.erase(i); 

     i = j; 
    } 

作爲exercice,移動duplicate = true跳出循環:

listName.sort(); 

    for(auto i = listName.begin(); i != listName.end();) 
    { 
     auto j = std::next(i); 
     bool duplicate = (j != listName.end() && *j == *i); 

     if(duplicate) 
     { 
      do 
      { 
       j = listName.erase(j); 
      }while(j != listName.end() && *j == *i); 

      listName.erase(i); 
     } 

     i = j; 
    }