Как использовать std :: unique для удаления уникального символа в векторе (c ++) - PullRequest
0 голосов
/ 04 декабря 2018

Мне нужно удалить уникальные символы в векторе 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 голосов
/ 04 декабря 2018

std::unique не делает то, что вам нужно здесь.Вам придется сделать что-то еще.

С эта ссылка (выделение мое)

Исключает все элементы, кроме первого, из каждой группы подряд эквивалентных элементов

Простой способ проверить, видел ли вы элемент ранее, - добавить его в набор.

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
0 голосов
/ 04 декабря 2018

РЕДАКТИРОВАТЬ: Этот ответ был применим к предыдущей, немного неясной версии вопроса.Для ответа на текущий вопрос см. Caleth's answer.


std::unique удаляет смежные дубликаты (фактически выталкивает их в конец заданногодиапазон, чтобы сделать их очень подходящими для последующего удаления с erase).Это не то, что вам нужно.

Если вы хотите удалить уникальные элементы, то я бы предложил решение, основанное на подсчете вхождений отдельных элементов и их удалении тех, которые встречаются только один раз.Посмотрите на эту функцию:

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) подталкивает элементы, которые удовлетворяют определенным критериям, к концу диапазона, чтобы сделать их пригодными для фактического удаления. определенные критерии в этом примере являются удовлетворением предиката - лямбды, которая проверяет, встречался ли данный элемент только один раз (эта информация предоставляется нашей картой, которую мы фиксируем в лямбде).После этого мы просто удаляем эти элементы с помощью вызова 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.Все уникальные элементы были удалены

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...