如何使用std :: unique删除向量中的唯一字符(C ++)

时间:2018-12-04 10:25:12

标签: c++ stl

我需要删除向量中的唯一字符 v.erase(unique(v.begin(),v.end())); 这是什么问题。
输入:wxwwm
输出:wxm

 `vector<string>v;    
  string s;   
  cin >>s;   
  v.push_back(s);   
  v.erase(unique(v.begin(),v.end()),v.end());     
  for(auto i=v.begin();i!=v.end();i++)    
  {  
   cout <<*i;  
   }`

2 个答案:

答案 0 :(得分:4)

编辑:此答案适用于问题的先前版本(略微不清楚)。有关当前问题的答案,请参见 Caleth's 答案。


std::unique删除相邻的重复项(实际上将它们推到给定范围的末尾,使它们非常适合以后使用erase删除)。那不是你想要的。

如果您想删除 unique 元素,那么我将提出一种解决方案,其基础是对不同元素的出现进行计数,并删除仅出现一次的元素。看一下这个功能:

template <typename T>
void remove_unique(std::vector<T>& vec) {
    std::map<T, int> occurrences {};

    for(const auto& element : vec) {
        occurrences[element]++;
    }

    const auto to_remove = std::remove_if(vec.begin(), vec.end(),
            [&occurrences](const auto& element) {
                return occurrences[element] == 1;
            }
    );

    vec.erase(to_remove, vec.end());
}

这将从包含任何类型的std::vector中删除所有唯一元素(假定它是可复制的)。

它使用std::map来计算向量中每个元素的出现,然后使用std::remove_if,这将(类似于std::unique)将满足特定条件的元素推送到范围的末端,以使其适合实际移除。在此示例中,某些条件是谓词的满足-lambda,它检查给定元素是否仅出现一次(此信息由我们的地图提供,我们在lambda中捕获)。然后,我们只需通过erase调用删除那些元素。

用法:

int main() {
    // two 2s and two 3s
    std::vector<int> vec {1, 2, 4, 3, 0, 2, 9, 3};

    remove_unique(vec);

    for(const auto i : vec) {
        std::cout << i << ' ';
    }
}

该程序的输出为:2 3 2 3。所有唯一元素均已删除

答案 1 :(得分:3)

std::unique不能满足您的要求。您将不得不做其他事情。

来自this reference(重点是我)

  

从等效元素的每个连续组中消除除第一个元素外的所有元素

测试以前是否看过元素的一种简单方法是将其添加到集合中。

std::string s = "wxwwm";
std::set<char> seen;
s.erase(std::remove_if(s.begin(), s.end(), [&seen](char c){ return !seen.insert(c).second; }), s.end());
std::cout << s; // outputs wxm