4.1 Example

Let us consider a word processor that needs to keep track of index entries. An index consists of two parts: the text of the index, and a destination address (which is a page number for a printed document, or an anchor for an HTML document). As a document is scanned, index items are collected.

When the document is about to be published, the index is rendered based on the alphabetical order of the text of each index item. Note that multiple index items may share the same index text, but have different destinations.

In this case, as we scan through (parse) the document, we need to insert items into a container. Even without knowing what kind of container will be chosen, we know that it needs to support an “insert iterator” to add entries into the container. Note that there are different types of insert iterators, some insert at the front, and some inert at the end.

When the document is rendered, the index must be generated. The generation of the index requires the contained index items be presented in a sorted fashion. This can be done by two methods. We can sort the container when the index needs to be rendered, or we can maintain index items already sorted in the container.

In this case, we have many choices. The most efficient method, however, is to use a vector as an underlying container, then use a back_insert_iterator to insert items into the container. When a document is parsed, then the program can use the stable_sort algorithm to sort the index entries. Once the entries are sorted, the vector iterator can be used to extract the index entries.

Listing 1 is a sample program to illustrate this example.


Listing 1:indexing
 
1#include <iostream> 
2#include <cstring> 
3#include <vector> 
4#include <string> 
5#include <iterator> 
6#include <ext/algorithm> 
7 
8using namespace std; 
9 
10class URL 
11{ 
12    char where[256]; 
13  public: 
14    const char *get(void) { return where; } 
15    void set(const char *src) { strncpy(where, src, 256); } 
16    URL(void) { where[0] = 0; } 
17    URL(const char *src) { set(src); } 
18}; 
19 
20class IndexLess : public less<pair<string, URL> > 
21{ 
22  public: 
23    bool operator()(const pair<string, URL> &x, 
24                    const pair<string, URL> &y) 
25    { 
26      return x.first < y.first; 
27    } 
28}; 
29 
30void testInsert(back_insert_iterator<vector<pair<string, URL> > > &i) 
31{ 
32  *i++ = pair<string, URL>("abc", URL("http://www.abc.com")); 
33  *i++ = pair<string, URL>("nbc", URL("http://www.nbc.com")); 
34  *i++ = pair<string, URL>("ARC", URL("http://www.arc.losrios.edu")); 
35} 
36 
37bool Index_less(const pair<string, URL> &x, 
38              const pair<string, URL> &y) 
39{ 
40  return x.first < y.first; 
41} 
42 
43void testSort(vector<pair<string, URL> >::iterator b, 
44              vector<pair<string, URL> >::iterator e, 
45              IndexLess lt) 
46{ 
47  stable_sort(b, e, lt); 
48} 
49 
50int main(void) 
51{ 
52  vector<pair<string, URL> > v; 
53  back_insert_iterator<vector<pair<string, URL> > > bii(v); 
54 
55  testInsert(bii); 
56  testSort(v.begin(), v.end(), IndexLess()); 
57  cout << "isthesequencesorted?" << 
58    is_sorted(v.begin(), v.end(), IndexLess()) << endl; 
59  for (vector<pair<string, URL> >::iterator i = v.begin(); 
60       i != v.end(); 
61       ++i) 
62  { 
63    cout << (*i).first << ":" << (*i).second.get() << endl; 
64  } 
65  return 0; 
66}