我有串的名單,我怎麼能在一個std ::列表中刪除重複的值,如刪除在一個std重複項目::名單
std::list<std::string> listName;
listName.push_back("Foo");
listName.push_back("Bar");
listName.push_back("Foo");
然後我想刪除重複的名字,其是「Foo」。剩下的只是「酒吧」的名字。
謝謝!
我有串的名單,我怎麼能在一個std ::列表中刪除重複的值,如刪除在一個std重複項目::名單
std::list<std::string> listName;
listName.push_back("Foo");
listName.push_back("Bar");
listName.push_back("Foo");
然後我想刪除重複的名字,其是「Foo」。剩下的只是「酒吧」的名字。
謝謝!
如果你只想在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你能做到這一點
OP表示只剩下「Bar」。這也會有「Foo」。 –
我只是做了這種做法,它是錯誤的,因爲OP要'而剩下的只是「酒吧」的名字。' – billz
人們需要仔細閱讀這個問題,並停止推薦'list :: unique()':) –
的一種方法是使用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;
}
排序列表,那麼你可以很容易地找到重複的。
#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;
}
@DyP:該OP希望除去重複項的所有實例(即如果「foo」出現兩次,ALL「foo」將被刪除,'list :: unique()'不會這樣做) –
@JonathanPotter哦!良好的漁獲 – dyp