开发者

How can I remove duplicate values from a list in c++? [closed]

开发者 https://www.devze.com 2023-02-08 08:04 出处:网络
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers. 开发者_Go百科

Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist

Closed 9 years ago.

Improve this question

I am new to c++ and stuck to a problem. I am using list for storing string values. now i want to remove the duplicate values from that string. Can anyone tell me how do this.

Any sample code will be highly appreciate.


Use sort followed by unique.


If the list is sorted, use its unique method.

If the list isn't sorted (and you don't want to sort it):

set<string> found;
for (list<string>::iterator x = the_list.begin(); x != the_list.end();) {
  if (!found.insert(*x).second) {
    x = the_list.erase(x);
  }
  else {
    ++x;
  }
}

To avoid copying the strings into the set:

struct less {
  template<class T>
  bool operator()(T &a, T &b) {
    return std::less<T>()(a, b);
  }
};
struct deref_less {
  template<class T>
  bool operator()(T a, T b) {
    return less()(*a, *b);
  }
};

void remove_unsorted_dupes(list<string> &the_list) {
  set<list<string>::iterator, deref_less> found;
  for (list<string>::iterator x = the_list.begin(); x != the_list.end();) {
    if (!found.insert(x).second) {
      x = the_list.erase(x);
    }
    else {
      ++x;
    }
  }
}


If you have an std::list you can remove duplicates with:

yourlist.sort();
yourlist.unique();


Use unique().

But first sort() the list, or unique won't do what you expect.


Solution 1:

struct already_found
{
  std::set<std::string> & theSet;

  bool operator()(const std::string& s) const
  {
     return !theSet.insert(s).second;
  }
};

std::set<std::string> theSet;
the_list.remove_if( the_list.begin(), the_list.end(), already_found(theSet) );

Solution 2 using shared_ptr

struct already_found
{
  boost::shared_ptr<std::set<std::string> > theSet;
  already_found() : theSet( new boost::shared_ptr<std::set<std::string> > )
  {
  }

  bool operator()(const std::string& s) const
  {
     return !theSet->insert(s).second;
  }
};

the_list.remove_if( the_list.begin(), the_list.end(), already_found(theSet) );

These both have the disadvantage of having to copy all the strings. You can slightly optimise this by storing pointers to the strings and comparing them with a custom compare.

0

精彩评论

暂无评论...
验证码 换一张
取 消