By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,734 Members | 880 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,734 IT Pros & Developers. It's quick & easy.

find_if algorithm on multimaps

P: n/a
Hello,
Could someone tell me why the find_if statement applied to my multimap
dictionnary is doesn't compile? Does this algorithm doesn't work on a
multimap?

I don't understand why the adjacent_find compile and not the find_if
statement?

By the way my first intention was to write:
find_if (j, dictionnary.end(), bind1st (not_equal_to <string> (), *j));
but it doesn't compile neither for the same reason I guess.

Thanks by advance,
devel.

#include <iostream>
#include <map>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
#include <functional>

using namespace std;

typedef multimap<string, string, less <string> > MapDictionnary;

int
main (int argc, char **argv)
{
string dictionnaryName;
cout << "Enter dictionnary name :";
cin >> dictionnaryName;

MapDictionnary dictionnary;
ifstream dictionnaryIFStream (dictionnaryName.c_str());
istream_iterator<string> it;
for (it=istream_iterator<string> (dictionnaryIFStream);
it!=istream_iterator<string> (); ++it)
{
vector<char> sortedString ((*it).begin(), (*it).end());
sort (sortedString.begin(), sortedString.end());
dictionnary.insert (make_pair<string, string>
(string(sortedString.begin(), sortedString.end()), (*it)));
}

cout << "The dictionnary " << dictionnaryName << " contains " <<
dictionnary.size() << " words." << endl;

MapDictionnary::iterator j=dictionnary.begin();
MapDictionnary::iterator k;
while (true)
{
j=adjacent_find (j, dictionnary.end(), dictionnary.value_comp());
if (j==dictionnary.end())
break;

// INCORECT FIND_IF STATEMENT !! k=find_if (j, dictionnary.end(),
dictionnary.value_comp());
// End of : INCORECT FIND_IF STATEMENT !!
};

return 0;
}
Apr 9 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
devel wrote:
Hello,
Could someone tell me why the find_if statement applied to my multimap
dictionnary is doesn't compile? Does this algorithm doesn't work on a
multimap?

I don't understand why the adjacent_find compile and not the find_if
statement?

By the way my first intention was to write:
find_if (j, dictionnary.end(), bind1st (not_equal_to <string> (), *j));
but it doesn't compile neither for the same reason I guess.

Thanks by advance,
devel.

#include <iostream>
#include <map>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
#include <functional>

using namespace std;

typedef multimap<string, string, less <string> > MapDictionnary;

int
main (int argc, char **argv)
{
string dictionnaryName;
cout << "Enter dictionnary name :";
cin >> dictionnaryName;

MapDictionnary dictionnary;
ifstream dictionnaryIFStream (dictionnaryName.c_str());
istream_iterator<string> it;
for (it=istream_iterator<string> (dictionnaryIFStream);
it!=istream_iterator<string> (); ++it)
{
vector<char> sortedString ((*it).begin(), (*it).end());
sort (sortedString.begin(), sortedString.end());
dictionnary.insert (make_pair<string, string>
(string(sortedString.begin(), sortedString.end()), (*it)));
}

cout << "The dictionnary " << dictionnaryName << " contains " <<
dictionnary.size() << " words." << endl;

MapDictionnary::iterator j=dictionnary.begin();
MapDictionnary::iterator k;
while (true)
{
j=adjacent_find (j, dictionnary.end(), dictionnary.value_comp());
if (j==dictionnary.end())
break;

// INCORECT FIND_IF STATEMENT !! k=find_if (j,
dictionnary.end(), dictionnary.value_comp());
// End of : INCORECT FIND_IF STATEMENT !!
};

return 0;
}


Ok, I see my mistake find_if takes an unary predicate.
My question is why
k=find_if (j, dictionnary.end(), bind1st (not_equal_to <string> (),
(*j).first));

doesn't work?

Thanks by advance,
devel.

PS: The compiler output is:

/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/bits/stl_algo.h:
In function `_InputIterator std::find_if(_InputIterator, _InputIterator,
_Predicate, std::input_iterator_tag) [with _InputIterator =
std::_Rb_tree_iterator<std::pair<const std::string, std::string> >,
_Predicate = std::binder1st<std::not_equal_to<std::string> >]':
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/bits/stl_algo.h:336:
instantiated from `_InputIterator std::find_if(_InputIterator,
_InputIterator, _Predicate) [with _InputIterator =
std::_Rb_tree_iterator<std::pair<const std::string, std::string> >,
_Predicate = std::binder1st<std::not_equal_to<std::string> >]'
stl_tut_ref_guide_chap13.cc:40: instantiated from here
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/bits/stl_algo.h:187:
erreur: pas de concordance pour l'appel de
(std::binder1st<std::not_equal_to<std::string> >) (std::pair<const
std::string, std::string>&)
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/bits/stl_function.h:406:
note: candidats sont: typename _Operation::result_type
std::binder1st<_Operation>::operator()(const typename
_Operation::second_argument_type&) const [with _Operation =
std::not_equal_to<std::string>]
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/bits/stl_function.h:412:
note: typename _Operation::result_type
std::binder1st<_Operation>::operator()(typename
_Operation::second_argument_type&) const [with _Operation =
std::not_equal_to<std::string>]

Apr 9 '06 #2

P: n/a

devel wrote:
Ok, I see my mistake find_if takes an unary predicate.
My question is why
k=find_if (j, dictionnary.end(), bind1st (not_equal_to <string> (),
(*j).first));

doesn't work?


Dereferencing your iterator yields pair<string const, string>. There is
no compare operators declared for the pair and the string needed. Roll
out your own predicate object or use boost::bind/lambda.

Apr 9 '06 #3

P: n/a
In article <44***********************@news.free.fr>,
devel <"devel at free dot fr"> wrote:
Hello,
Could someone tell me why the find_if statement applied to my multimap
dictionnary is doesn't compile? Does this algorithm doesn't work on a
multimap?

I don't understand why the adjacent_find compile and not the find_if
statement?

By the way my first intention was to write:
find_if (j, dictionnary.end(), bind1st (not_equal_to <string> (), *j));
but it doesn't compile neither for the same reason I guess.

Thanks by advance,
devel.

#include <iostream>
#include <map>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
#include <functional>

using namespace std;

typedef multimap<string, string, less <string> > MapDictionnary;

int
main (int argc, char **argv)
{
string dictionnaryName;
cout << "Enter dictionnary name :";
cin >> dictionnaryName;

MapDictionnary dictionnary;
ifstream dictionnaryIFStream (dictionnaryName.c_str());
istream_iterator<string> it;
for (it=istream_iterator<string> (dictionnaryIFStream);
it!=istream_iterator<string> (); ++it)
{
vector<char> sortedString ((*it).begin(), (*it).end());
sort (sortedString.begin(), sortedString.end());
dictionnary.insert (make_pair<string, string>
(string(sortedString.begin(), sortedString.end()), (*it)));
The above is harder than it needs to be. Instead of a vector<char> use a
string. See my code below for an example.
}

cout << "The dictionnary " << dictionnaryName << " contains " <<
dictionnary.size() << " words." << endl;

MapDictionnary::iterator j=dictionnary.begin();
MapDictionnary::iterator k;
while (true)
{
j=adjacent_find (j, dictionnary.end(), dictionnary.value_comp());
The only way 'j' will *not* equal 'end()' is if the same word is in the
file without any intervening words that use the same letters. For
example, if the file contained "time mite emit time mite emit", 'j'
would equal end(). Is this really what you want?

if (j==dictionnary.end())
break;

// INCORECT FIND_IF STATEMENT !! k=find_if (j, dictionnary.end(),
dictionnary.value_comp());
// End of : INCORECT FIND_IF STATEMENT !!
};

return 0;
}


(By this point, your function is way to long and trying to do too much.
Was this just for example purposes?)

If you are trying to stop duplicate entries then a different structure
may be called for:
----------------------------------------------------------------------
typedef map< string, set<string> > MapDict;

void extractWords( istream& is, MapDict& dict ) {
istream_iterator<string> it( is );
while ( it != istream_iterator<string>() ) {
string entry( *it );
sort( entry.begin(), entry.end() );
dict[entry].insert( *it );
++it;
}
}

int main() {
cout << "Enter file name: ";
string name;
cin >> name;
MapDict dict;
extractWords( ifstream( name ), dict );
// use dict here
}
----------------------------------------------------------------------
'std::set' will automatically remove duplicates, and sort the entries.

If you really want it in a multimap, then after applying the above you
can:
----------------------------------------------------------------------
int main() {
cout << "Enter file name: ";
string name;
cin >> name;
MapDict dict;
ifstream file( name );
extractWords( file, dict );
multimap< string, string > expandedDict;
for ( MapDict::iterator it = dict.begin(); it != dict.end(); ++it )
for ( set<string>::iterator it2 = it->second.begin();
it2 != it->second.end(); ++it2 )
expandedDict.insert( make_pair( it->first, *it2 ) );
// use expandedDict
}
----------------------------------------------------------------------

If it must be a multimap from the beginning, then you should make your
check for duplicates before the insert, because trying to remove
duplicates after the fact would be really hairy.

----------------------------------------------------------------------
typedef multimap< string, string > MapDict;

// with just a little work, this can be made much more general...
// I leave that as an exorcise. :-)
struct second_is : unary_function< string, bool > {
string value;
second_is( string v ): value( v ) { }
bool operator()( MapDict::value_type v ) const {
return v.second == value;
}
};

void extractWords( istream& is, MapDict& dict ) {
istream_iterator<string> it( is );
while ( it != istream_iterator<string>() ) {
string entry( *it );
sort( entry.begin(), entry.end() );
pair< MapDict::iterator, MapDict::iterator > range =
dict.equal_range( entry );
if ( find_if( range.first, range.second, second_is( *it ) ) ==
range.second )
dict.insert( make_pair( entry, *it ) );
++it;
}
}
----------------------------------------------------------------------


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Apr 10 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.