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.