int Xgen::i = 0;
typedef multiset
typedef Xmset::const_iterator Xmit;
int main() {
Xmset mset;
// Fill it with X's:
generate_n(inserter(mset, mset.begin()),
25, Xgen());
// Initialize a regular set from mset:
set
copy(unique.begin(), unique.end(),
ostream_iterator
cout << "\n----\n";
// Iterate over the unique values:
for(set
i != unique.end(); i++) {
pair
copy(p.first, p.second,
ostream_iterator
cout << endl;
}
} ///:~
In X, all the comparisons are made with the char c. The comparison is performed with operator<, which is all that is necessary for the multiset, since in this example the default less comparison object is used. The class Xgen randomly generates X objects, but the comparison value is restricted to the span from ‘A’ to ‘E’. In main( ), a multiset
As a second example, a (possibly) more elegant version of WordCount.cpp can be created using multiset:
//: C07:MultiSetWordCount.cpp
// Count occurrences of words using a multiset
#include
#include
#include
#include
#include
#include "../require.h"
using namespace std;
int main(int argc, char* argv[]) {
char* fname = "MultiSetWordCount.cpp";
if(argc > 1) fname = argv[1];
ifstream in(fname);
assure(in, fname);
multiset
string word;
while(in >> word)
wordmset.insert(word);
typedef multiset
MSit it = wordmset.begin();
while(it != wordmset.end()) {
pair
int count = distance(p.first, p.second);
cout << *it << ": " << count << endl;
it = p.second; // Move to the next word
}
} ///:~
The setup in main( ) is identical to WordCount.cpp, but then each word is simply inserted into the multiset
In the end, is this really a "set," or should it be called something else? An alternative is the generic "bag" that is defined in some container libraries, since a bag holds anything at all without discrimination—including duplicate objects. This is close, but it doesn’t quite fit since a bag has no specification about how elements should be ordered. A multiset (which requires that all duplicate elements be adjacent to each other) is even more restrictive than the concept of a set, which could use a hashing function to order its elements, in which case they would not be in sorted order. Besides, if you wanted to store a bunch of objects without any special criteria, you’d probably just use a vector, deque, or list.
Combining STL containers
When using a thesaurus, you want to know all the words that are similar to a particular word. When you look up a word, then, you want a list of words as the result. Here, the "multi" containers (multimap or multiset) are not appropriate. The solution is to combine containers, which is easily done using the STL. Here, we need a tool that turns out to be a powerful general concept, which is a map of vector:
//: C07:Thesaurus.cpp
// A map of vectors
//{-msc}
//{-g++}
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef map
typedef pair
typedef Thesaurus::iterator TIter;
ostream& operator<<(ostream& os,const TEntry& t){
os << t.first << ": ";
copy(t.second.begin(), t.second.end(),
ostream_iterator
return os;
}
// A generator for thesaurus test entries:
class ThesaurusGen {
static const string letters;
static int count;
public:
int maxSize() { return letters.size(); }
ThesaurusGen() { srand(time(0)); }
TEntry operator()() {
TEntry result;