Article directory
1 Concept
1.1 map
map:
Associated container:
- 1 will sort key values from small to large (internal implementation: red black tree);
- 2 if the string is mapped to an integer, string must be used instead of char array;
- Using iterator, we can find the key value and the mapped value at the same time;
- 4 stored key value pair, unique key value.
1.2 pair
pair:
Header file: < utility >
As a simplified version of map, it often replaces binary structure and constructor.
Internal implementation of data structure:
struct pair{ typeName1 first; typeName2 second; }
You can compare (= =, >, > =, <, < =,! =). First, take the size of first as the standard, and then judge second only when the first is equal.
For a mapping table with key type K and value type V, the associated pair type is pair < const K, V >. The key is a constant, so the key value of the element cannot be modified, and if it is not a constant, we may modify it.
2 map usage example
2.1 problem description
Use mapping table to write a program that describes a statement structure (or syntax) and can generate random statements that match this description.
For example: can describe an English sentence as a noun and a verb or a combination of a noun or verb and an object.
For example, the following is the result of the program:
2.2 way of thinking
- 1 read grammar
- The expression rules of grammar are;
- Vector < string > rule; indicates the type of rule (such as verb and noun)
- Vector < rule > rule_collection; indicates the type of rule collection; (for example, the syntax specification at the beginning of < sentence >)
- Map < string, rule_collection > grammar; indicates the type of mapping table; (for example, < V > corresponds to bits, jumps, < sentence > corresponds to the < nm > < V > < p >)
- Take the first type of each statement as the key, and the string after it as the mapped value
- The expression rules of grammar are;
- 2 generate statement
- Find a rule corresponding to < sentence >, then construct the output in sections, and output the contents of different rules and rules.
- 3 select random elements
##2.3 implementation code
//Sentence making #include <iostream> #include <map> #include <string> #include <vector> #include <cctype> #include <stdexcept> #include <cstdlib> using std::cin; using std::cout; using std::endl; using std::map; using std::string; using std::vector; using std::istream; using std::logic_error; using std::domain_error; typedef vector<string> Rule; typedef vector<Rule> Rule_collection; typedef map<string, Rule_collection> Grammar; //Yes blank area is true bool space(char c){ return isspace(c); } //Not blank area is true bool not_space(char c){ return !isspace(c); } vector<string> split(const string& str){ typedef string::const_iterator iter; vector<string> ret; iter i = str.begin(); while(i != str.end()){ //Ignore preceding blanks i = find_if(i, str.end(), not_space); //Find the end of the next word iter j = find_if(i , str.end(), space); //Characters copied in [I, J] if(i != str.end()){ ret.push_back(string(i, j)); } i = j; } return ret; } Grammar read_grammar(istream& in){ Grammar ret; string line; while(getline(in, line)){ //Split input into single words vector<string> entry = split(line); if(!entry.empty()){ //Use types to store associated rules ret[entry[0]].push_back(Rule(entry.begin()+1, entry.end())); } } return ret; } bool backeted(const string& s){ return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>'; } int nrand(int n){ if(n <= 0 || n > RAND_MAX){ throw domain_error("Argument to nrand is out of range"); } const int bucket_size = RAND_MAX / n; int r; do{ r = rand()/bucket_size; }while(r >= n); return r; } void gen_aux(const Grammar& g, const string& word, vector<string>& ret){ if(!backeted(word)){ ret.push_back(word); }else{ //Locate the corresponding word rule Grammar::const_iterator it = g.find(word); if(it == g.end()){ throw logic_error("empty rule"); } //Get possible rules const Rule_collection& c = it->second;//Enter vector < vector < string > > //Randomly select a rule from the rule set const Rule& r = c[nrand(c.size())];//To vector < string > for (Rule::const_iterator i = r.begin(); i != r.end(); ++i) { gen_aux(g, *i, ret); } } } vector<string> gen_sentence(const Grammar& g){ vector<string> ret; //Expand the string passed by the second parameter //Find the string in the grammar (statement structure) of the first parameter and put its output in the third parameter gen_aux(g, "<sentence>", ret); return ret; } int main(int argc, char const *argv[]){ vector<string> sentence = gen_sentence((read_grammar(cin))); vector<string>::const_iterator it = sentence.begin(); if(!sentence.empty()){ cout << *it; ++it; } while(it != sentence.end()){ cout <<" " <<*it; ++it; } cout << endl; return 0; } /* <sentence> the <nm> <v> <p> <n> cat <n> dog <n> table <nm> <n> <nm> <a> <nm> <a> large <a> brown <a> absurd <v> sits <v> jumps <p> on te stairs <p> under the sky <p> wherever it wants */