Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete elements in a std::vector<std::string> which matches with the characters in another given std::string

How can I remove elements in the vector alphabets which matches with any of the characters in the string plaintext?

Here's my attempt:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main()
{
   //init
   std::vector<std::string> alphabets{ "a", "b", "c", "d", "e", "f", "g", "h", "i", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
   //input
   std::string plaintext;
   std::cout << "enter plain text: ";
   std::cin >> plaintext;

   for (std::string::iterator it = plaintext.begin(); it != plaintext.end(); it++)
   {
      std::vector<std::string>::iterator toErase;
      toErase = std::find(alphabets.begin(), alphabets.end(), *it);
      if (toErase != alphabets.end())
      {
         alphabets.erase(toErase);
      }
   }
}

When I tried to compile it. But I got this error:

17: note:   'std::__cxx11::basic_string<char>' is not derived from
'const std::istreambuf_iterator<_CharT, _Traits>' { return *__it == _M_value; }
...

203 : 5 : note : candidate : 'template<class _CharT, class _Traits> bool 
std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const
   std::istreambuf_iterator<_CharT, _Traits>&)'
   operator==(const istreambuf_iterator<_CharT, _Traits> & __a,
      ...
like image 703
Bala Ganesh Avatar asked Aug 31 '20 07:08

Bala Ganesh


People also ask

How do I remove an element from a vector string in C++?

To remove all copies of an element from a vector , you can use std::remove like this: v. erase(std::remove(v. begin(), v.

How do you pop an element from a vector in C++?

C++ pop_back() function is used to pop or remove elements from a vector from the back. The value is removed from the vector from the end, and the container size is decreased by 1.

What is an std:: vector?

1) std::vector is a sequence container that encapsulates dynamic size arrays. 2) std::pmr::vector is an alias template that uses a polymorphic allocator. The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements.


1 Answers

The *it has a type of char not std::string. This is what the compiler complaining about. Therefore you need to pass a std::string to the std::find as follows.

auto toErase = std::find(alphabets.begin(), alphabets.end(), std::string{ *it });
 //                                                          ^^^^^^^^^^^^^^^^^^

Here is a demo.


Also, note the followings:

  • You can change the std::vector<std::string> alphabets to a std::vector<char> alphabets or even a single std::string as your alphabets containes/ represents chars as strings. In the case of std::strings (i.e. alphabets), the std::basic_string::find is more appropriate to use, rather than having more general std::find at first place.
  • For vector erase, you could use erase–remove idiom, or since C++20, using non-member function of std::vector itself, so called std::erase_if.
like image 119
JeJo Avatar answered Sep 21 '22 12:09

JeJo