| 1 | // Boost.Bimap |
| 2 | // |
| 3 | // Copyright (c) 2006-2007 Matias Capeletto |
| 4 | // |
| 5 | // Distributed under the Boost Software License, Version 1.0. |
| 6 | // (See accompanying file LICENSE_1_0.txt or copy at |
| 7 | // http://www.boost.org/LICENSE_1_0.txt) |
| 8 | |
| 9 | |
| 10 | // Boost.Bimap Example |
| 11 | //----------------------------------------------------------------------------- |
| 12 | // Hashed indices can be used as an alternative to ordered indices when fast |
| 13 | // lookup is needed and sorting information is of no interest. The example |
| 14 | // features a word counter where duplicate entries are checked by means of a |
| 15 | // hashed index. |
| 16 | |
| 17 | #include <boost/config.hpp> |
| 18 | |
| 19 | //[ code_mi_to_b_path_hashed_indices |
| 20 | |
| 21 | #include <iostream> |
| 22 | #include <iomanip> |
| 23 | |
| 24 | #include <boost/tokenizer.hpp> |
| 25 | |
| 26 | #include <boost/bimap/bimap.hpp> |
| 27 | #include <boost/bimap/unordered_set_of.hpp> |
| 28 | #include <boost/bimap/multiset_of.hpp> |
| 29 | #include <boost/bimap/support/lambda.hpp> |
| 30 | |
| 31 | using namespace boost::bimaps; |
| 32 | |
| 33 | struct word {}; |
| 34 | struct occurrences {}; |
| 35 | |
| 36 | typedef bimap |
| 37 | < |
| 38 | |
| 39 | multiset_of< tagged<unsigned int,occurrences>, std::greater<unsigned int> >, |
| 40 | unordered_set_of< tagged< std::string, word> > |
| 41 | |
| 42 | > word_counter; |
| 43 | |
| 44 | typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer; |
| 45 | |
| 46 | int main() |
| 47 | { |
| 48 | |
| 49 | std::string text= |
| 50 | "Relations between data in the STL are represented with maps." |
| 51 | "A map is a directed relation, by using it you are representing " |
| 52 | "a mapping. In this directed relation, the first type is related to " |
| 53 | "the second type but it is not true that the inverse relationship " |
| 54 | "holds. This is useful in a lot of situations, but there are some " |
| 55 | "relationships that are bidirectional by nature." ; |
| 56 | |
| 57 | // feed the text into the container |
| 58 | |
| 59 | word_counter wc; |
| 60 | text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-" )); |
| 61 | unsigned int total_occurrences = 0; |
| 62 | |
| 63 | for( text_tokenizer::const_iterator it = tok.begin(), it_end = tok.end(); |
| 64 | it != it_end ; ++it ) |
| 65 | { |
| 66 | ++total_occurrences; |
| 67 | |
| 68 | word_counter::map_by<occurrences>::iterator wit = |
| 69 | wc.by<occurrences>().insert( |
| 70 | x: word_counter::map_by<occurrences>::value_type(0,*it) |
| 71 | ).first; |
| 72 | |
| 73 | wc.by<occurrences>().modify_key( position: wit, mod: ++_key); |
| 74 | } |
| 75 | |
| 76 | // list words by frequency of appearance |
| 77 | |
| 78 | std::cout << std::fixed << std::setprecision(2); |
| 79 | |
| 80 | for( word_counter::map_by<occurrences>::const_iterator |
| 81 | wit = wc.by<occurrences>().begin(), |
| 82 | wit_end = wc.by<occurrences>().end(); |
| 83 | |
| 84 | wit != wit_end; ++wit ) |
| 85 | { |
| 86 | std::cout << std::setw(15) << wit->get<word>() << ": " |
| 87 | << std::setw(5) |
| 88 | << 100.0 * wit->get<occurrences>() / total_occurrences << "%" |
| 89 | << std::endl; |
| 90 | } |
| 91 | |
| 92 | return 0; |
| 93 | } |
| 94 | //] |
| 95 | |