2

I try to make a set to store certain words of a text file. Then I want to remove these words from a map, which I already made up. I have successfully made a set to store these words, but I cannot remove them from the map. Besides, I cannot use a loop statement(like for loop or while loop).

#include <iostream>
#include <iomanip>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <list>

  ifstream stop_file( "remove_words.txt" );
  ofstream out( "output.txt" );

  set <string> S;

  copy(istream_iterator<string>(stop_file), 
       istream_iterator<string>(),
       inserter(S, begin(S)));

         //copy: copy from text file into a set

  remove_if(M.begin(), M.end(), S);

        //remove: function I try to remove words among words stored in a map
        //map I made up is all set, no need to worry
Frank
  • 91
  • 7

2 Answers2

0

Could you provide the declaration of your map?

For example, if the map is map<string, int> you can do something like this:

for (string & s : set)
{
    map.erase(s);
}

Using for_each would look like this:

std::for_each(set.begin(), set.end(), 
    [&map](const std::string & s) { map.erase(s); });

Also, using recursion it is possible to do the removal with no loops at all

template <typename Iter>
void remove_map_elements(
    std::map<std::string, int> & map,
    Iter first,
    Iter last)
{
    if (first == last || map.empty())
        return;

    map.erase(*first);
    remove_map_elements(map, ++first, last);
}

which you call like

 remove_map_elements(map, set.begin(), set.end());
philm
  • 46
  • 3
  • It should be `const string&` because the `std::set::iterator` is a constant iterator. It does not compile without `const`. –  Nov 26 '15 at 03:34
  • yes, thank you. my map is But I really need another way to remove words without writing a for loop. though, for_each is applicable. – Frank Nov 26 '15 at 03:34
  • @Dorothy Why can't you use a for loop? It has to do some kind of loop at some point. Also the most efficient way would require you to write your own for loop to take into account the ordering of the set and map. A naive solution will perform a full log lookup each erase. – Neil Kirk Nov 26 '15 at 03:57
  • @NeilKirk I'm sorry I didn't mention. Actually it is an assignment, I was learning high-level C++ loops so I can't. – Frank Nov 26 '15 at 04:34
0

If I understand it correctly, you need something like that:

  std::map< std::string, int > m = {
    { "word1", 1 },
    { "word2", 2 },
    { "word3", 3 },
    { "word4", 4 }
  };

  std::set< std::string > wordsToRemove = { "word2" };

  std::for_each( 
    wordsToRemove.begin(), 
    wordsToRemove.end(), 
    [&m] ( const std::string& word )   
    { 
      m.erase( word );  
    } 
  );
mvd
  • 246
  • 1
  • 7