|
|
The tutorial ``Associative Arrays in C++ - Map(3C++)'' develops a short program that uses a Map(3C++) to count how many times each distinct word occurs in its input:
#include <String.h> #include <Map.h> #include <iostream.h> main() { Map<String,int> count; String word;
while (cin >> word) count[word]++; cout << "COUNT\ tWORD\ n\ n"; Mapiter<String,int> p(count); while (++p) cout << p.value() << "\ t" << p.key() << endl; }
If lexicographic ordering of the output is not important (for example, if we are concerned only with knowing how many times each word occurs), then a Bag<String> offers just the functionality needed:
#include <String.h> #include <Set.h> #include <iostream.h> main(){ Bag<String> count; String word;
while(cin >> word){ count.insert(word); } Bagiter<String> bi(count); const Bag_pair<String>* p; cout << "COUNT\ tWORD\ n\ n";
while(p = bi.next()){ cout << p->count << "\ t" << p->value << "\ n"; } } Set_or_Bag_hashval Bag<String>::hash(const String& s){ return ((Set_or_Bag_hashval)s.hashval()); }
First note that the header file Set.h contains
the definitions needed to declare and implement Bags as well as Sets and pointer
sets. Like the Set<>, the Bag<String>
needs a hash
function, which we implement
using String's own hash function.
(The
String(3C++)
hash function is not perfect,
but it is fast and does quite a good job.)
Bag iterators
return pointers, not
to elements, but to pairs
consisting of an element and its multiplicity.
Running this program on an input stream
consisting of this sentence alone gives:
COUNT WORD 1 an 1 stream 1 of 1 gives: 2 this 1 Running 1 consisting 1 sentence 1 on 1 alone 1 input 1 program
Compare this with the output of the Map version:
COUNT WORD 1 Running 1 alone 1 an 1 consisting 1 gives: 1 input 1 of 1 on 1 program 1 sentence 1 stream 2 this
As expected, the only difference is that the Map version produces sorted output. We will look at the performance of these two programs in the section, ``Space-time tradeoffs''.