Map is an associated container of STL, which provides one-to-one (the first can be called a keyword, each keyword can only appear once in map, and the second can be called the value of this keyword) because of this feature, it is possible to provide a quick channel for programming when we process one-to-one data. Here, we will talk about the organization of map internal data. Within map, we will build a red/black tree (a non-strictly balanced binary tree), which has the ability to automatically sort data, therefore, all the data in the map is ordered, and we will see the benefits of ordering later.
The following is an example of one-to-one data ing. For example, in a class, each student's student ID has a one-to-one ing relationship with his name. This model may be easily described using map. Obviously, the student ID is described using Int, the name is described with a string (this article does not use char * to describe the string, but uses string in STL). The following describes the map description code:
Map <int, string> mapstudent;
1. Map Constructor
Map provides a total of six constructor functions, which involve the memory distributor and are omitted from the table. Below we will see some map constructor methods, we usually construct a map using the following method:
Map <int, string> mapstudent;
2. Data insertion
After constructing the map container, We can insert data into it. Here are three data insertion methods:
First, use the insert function to insert pair data. The following example shows (although the following code is hand-written, it can be compiled in VC and GCC. You can run it to see the effect, add this statement to VC to block the 4786 warning # pragma warning (Disable: 4786 ))
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent. insert (pair <int, string> (1, "student_one "));
Mapstudent. insert (pair <int, string> (2, "student_two "));
Mapstudent. insert (pair <int, string> (3, "student_three "));
Map <int, string >:: iterator ITER;
For (iter = mapstudent. Begin (); iter! = Mapstudent. End (); ITER ++)
{
Cout <ITER-> first <"<ITER-> second <end;
}
}
Type 2: Use the insert function to insert value_type data. The following is an example.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent. insert (Map <int, string>: value_type (1, "student_one "));
Mapstudent. insert (Map <int, string >:: value_type (2, "student_two "));
Mapstudent. insert (Map <int, string >:: value_type (3, "student_three "));
Map <int, string >:: iterator ITER;
For (iter = mapstudent. Begin (); iter! = Mapstudent. End (); ITER ++)
{
Cout <ITER-> first <"<ITER-> second <end;
}
}
Method 3: insert data using arrays. The following is an example.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent [1] = "student_one ";
Mapstudent [2] = "student_two ";
Mapstudent [3] = "student_three ";
Map <int, string >:: iterator ITER;
For (iter = mapstudent. Begin (); iter! = Mapstudent. End (); ITER ++)
{
Cout <ITER-> first <"<ITER-> second <end;
}
}
Although the above three methods can be used to insert data, they are different. Of course, the first and second methods are the same in effect, and the insert function is used to insert data, the concept of uniqueness of a set is involved in data insertion. When a map contains this keyword, the insert operation cannot insert data, but the array method is different, it can overwrite the value corresponding to the previous keyword.
Mapstudent. insert (Map <int, string>: value_type (1, "student_one "));
Mapstudent. insert (Map <int, string>: value_type (1, "student_two "));
After the preceding two statements are executed, the value corresponding to the 1 keyword in map is "student_one", and the second statement does not take effect, this involves how we know whether the insert statement is successfully inserted. We can use pair to determine whether the insert statement is successful. The program is as follows:
Pair <Map <int, string >:: iterator, bool> insert_pair;
Insert_pair = mapstudent. insert (Map <int, string >:: value_type (1, "student_one "));
The second pair variable is used to determine whether the insert is successful. The first variable returns a map iterator. If the insert is successful, the insert_pair.second value should be true; otherwise, the value is false.
The following code is provided to demonstrate whether the insertion is successful.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Pair <Map <int, string >:: iterator, bool> insert_pair;
Insert_pair = mapstudent. insert (pair <int, string> (1, "student_one "));
If (insert_pair.second = true)
{
Cout <"insert successfully" <Endl;
}
Else
{
Cout <"insert failure" <Endl;
}
Insert_pair = mapstudent. insert (pair <int, string> (1, "student_two "));
If (insert_pair.second = true)
{
Cout <"insert successfully" <Endl;
}
Else
{
Cout <"insert failure" <Endl;
}
Map <int, string >:: iterator ITER;
For (iter = mapstudent. Begin (); iter! = Mapstudent. End (); ITER ++)
{
Cout <ITER-> first <"<ITER-> second <end;
}
}
You can use the following program to check the effect of Data overwrite with arrays.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent [1] = "student_one ";
Mapstudent [1] = "student_two ";
Mapstudent [2] = "student_three ";
Map <int, string >:: iterator ITER;
For (iter = mapstudent. Begin (); iter! = Mapstudent. End (); ITER ++)
{
Cout <ITER-> first <"<ITER-> second <end;
}
}
3. Map size
How do we know how much data has been inserted into the map? The size function can be used as follows:
Int nsize = mapstudent. Size ();
4. Data Traversal
Three methods are also provided to traverse the map.
First: the application's forward iterator, which is everywhere in the above example, skipped
Type 2: Apply the reversed-phase iterator. The following is an example to illustrate the effect. Run the program on your own.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent. insert (pair <int, string> (1, "student_one "));
Mapstudent. insert (pair <int, string> (2, "student_two "));
Mapstudent. insert (pair <int, string> (3, "student_three "));
Map <int, string >:: reverse_iterator ITER;
For (iter = mapstudent. rbegin (); iter! = Mapstudent. rend (); ITER ++)
{
Cout <ITER-> first <"<ITER-> second <end;
}
}
Method 3: Use the array method. The program description is as follows:
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent. insert (pair <int, string> (1, "student_one "));
Mapstudent. insert (pair <int, string> (2, "student_two "));
Mapstudent. insert (pair <int, string> (3, "student_three "));
Int nsize = mapstudent. Size ()
// The error is returned. It should be for (INT nindex = 1; nindex <= nsize; nindex ++)
// By rainfish
For (INT nindex = 0; nindex <nsize; nindex ++)
{
Cout <mapstudent [nindex] <end;
}
}
5. Search for data (including determining whether the keyword appears in map)
Here, we will understand the benefits of ensuring orderly data insertion by map.
There are many methods to determine whether a data (keyword) appears in map. Although the title here is a data search, there will be a lot of basic map usage here.
Three data search methods are provided here.
First, use the count function to determine whether a keyword exists. The disadvantage is that the data location cannot be located. Due to the characteristics of map, one-to-one ing relationship, it is determined that the return value of the count function has only two values, either 0 or 1. The returned value is 1.
Type 2: Use the find function to locate the data occurrence location. It returns an iterator. When the data appears, it returns the iterator of the data location, if there is no data to be searched in the map, the iterator returned by the map is equal to the iterator returned by the end function.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent. insert (pair <int, string> (1, "student_one "));
Mapstudent. insert (pair <int, string> (2, "student_two "));
Mapstudent. insert (pair <int, string> (3, "student_three "));
Map <int, string >:: iterator ITER;
Iter = mapstudent. Find (1 );
If (ITER! = Mapstudent. End ())
{
Cout <"find, the value is" <ITER-> second <Endl;
}
Else
{
Cout <"do not find" <Endl;
}
}
Method 3: This method is intended to determine whether or not data appears. However, I intend to explain it here.
Lower_bound function usage. This function is used to return the lower bound of the keyword to be searched (an iterator)
Upper_bound function usage. This function is used to return the upper bound of the keyword to be searched (an iterator)
For example, if the values of 1, 2, 3, and 4 have been inserted in the map, if lower_bound (2) is used, 2 is returned, and if the value of upper-bound (2) is used, 3 is returned.
The pai_range function returns a pair. The first variable in pair is the iterator returned by lower_bound. The second iterator in pair is the iterator returned by upper_bound. If the two iterators are equal, this keyword is not displayed in map.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent [1] = "student_one ";
Mapstudent [3] = "student_three ";
Mapstudent [5] = "student_five ";
Map <int, string >:: iterator ITER;
Iter = mapstudent. lower_bound (2 );
{
// The iterator of lower bound 3 is returned.
Cout <ITER-> second <Endl;
}
Iter = mapstudent. lower_bound (3 );
{
// The iterator of lower bound 3 is returned.
Cout <ITER-> second <Endl;
}
Iter = mapstudent. upper_bound (2 );
{
// The iterator of the upper bound 3 is returned.
Cout <ITER-> second <Endl;
}
Iter = mapstudent. upper_bound (3 );
{
// The iterator with the upper bound 5 is returned.
Cout <ITER-> second <Endl;
}
Pair <Map <int, string >:: iterator, Map <int, string >:: iterator> mappair;
Mappair = mapstudent. interval _range (2 );
If (mappair. First = mappair. Second)
{
Cout <"do not find" <Endl;
}
Else
{
Cout <"find" <Endl;
}
Mappair = mapstudent. interval _range (3 );
If (mappair. First = mappair. Second)
{
Cout <"do not find" <Endl;
}
Else
{
Cout <"find" <Endl;
}
}
6. Empty and empty data
The clear () function can be used to clear the data in the map to determine whether there is data in the map. The empty () function can be used. If it returns true, it indicates that the map is empty.
7. data deletion
Here, the erase function is used. It has three overloaded functions. The usage of these functions is described in detail in the example below.
# Include <map>
# Include <string>
# Include <iostream>
Using namespace STD;
Int main ()
{
Map <int, string> mapstudent;
Mapstudent. insert (pair <int, string> (1, "student_one "));
Mapstudent. insert (pair <int, string> (2, "student_two "));
Mapstudent. insert (pair <int, string> (3, "student_three "));
// If You Want To demonstrate the output effect, select one of the following, and the effect you see will be better.
// Use the iterator to delete 1.
Map <int, string >:: iterator ITER;
Iter = mapstudent. Find (1 );
Mapstudent. Erase (ITER );
// If you want to delete 1, use the keyword to delete
Int n = mapstudent. Erase (1); // If deleted, 1 is returned; otherwise, 0 is returned.
// Use an iterator to delete parts
// The Code clears the entire map
Mapstudent. earse (mapstudent. Begin (), mapstudent. End ());
// When you delete a part, it is also a STL feature. The delete interval is a set of pre-closed and post-open.
// Add the traversal code and print the output.
}
8. Other functions
There are swap, key_comp, value_comp, get_allocator, and other functions. I feel that these functions are not used in programming much, and they are omitted from the table. If you are interested, you can study them on your own.
9. Sort
Here we will talk about a relatively advanced usage. Sorting is a problem. By default, STL uses a smaller number for sorting. The above Code does not have any problems in sorting, because the above keyword is int type, it supports less than number calculation. In some special cases, for example, if the keyword is a struct, a problem occurs when sorting is involved because it is not less than number operation, insert and other functions cannot be used during compilation. The following two methods are provided to solve this problem.
The first type: less than the serial number overload, the program example
# Include <map>
# Include <string>
Using namespace STD;
Typedef struct tagstudentinfo
{
Int NID;
String strname;
} Studentinfo, * pstudentinfo; // Student Information
Int main ()
{
Int nsize;
// Map scores with student information
Map <studentinfo, int> mapstudent;
Map <studentinfo, int >:: iterator ITER;
Studentinfo;
Studentinfo. nid = 1;
Studentinfo. strname = "student_one ";
Mapstudent. insert (pair <studentinfo, int> (studentinfo, 90 ));
Studentinfo. nid = 2;
Studentinfo. strname = "student_two ";
Mapstudent. insert (pair <studentinfo, int> (studentinfo, 80 ));
For (iter = mapstudent. Begin (); iter! = Mapstudent. End (); ITER ++)
Cout <ITER-> first. NID <Endl <ITER-> first. strname <Endl <ITER-> second <Endl;
}
The above program cannot be compiled, as long as the reload is smaller than the number, it will be OK, as shown below:
Typedef struct tagstudentinfo
{
Int NID;
String strname;
Bool operator <(tagstudentinfo const & _ A) const
{
// This function specifies the sorting policy, which is sorted by NID. If NID is the same, it is sorted by strname.
If (NID <_ A. NID) return true;
If (nid = _ A. NID) return strname. Compare (_ A. strname) <0;
Return false;
}
} Studentinfo, * pstudentinfo; // Student Information
Type 2: the application of the imitation function. At this time, there is no direct minor overload in the struct.
# Include <map>
# Include <string>
Using namespace STD;
Typedef struct tagstudentinfo
{
Int NID;
String strname;
} Studentinfo, * pstudentinfo; // Student Information
Classs sort
{
Public:
Bool operator () (studentinfo const & _ A, studentinfo const & _ B) const
{
If (_ A. NID <_ B. NID) return true;
If (_ A. nid = _ B. NID) return _ A. strname. Compare (_ B. strname) <0;
Return false;
}
};
Int main ()
{
// Map scores with student information
Map <studentinfo, Int, sort> mapstudent;
Studentinfo;
Studentinfo. nid = 1;
Studentinfo. strname = "student_one ";
Mapstudent. insert (pair <studentinfo, int> (studentinfo, 90 ));
Studentinfo. nid = 2;
Studentinfo. strname = "student_two ";
Mapstudent. insert (pair <studentinfo, int> (studentinfo, 80 ));
}
10. In addition
Since STL is a unified whole, many usage of map is combined with other things in STL. For example, in sorting, less signs are used by default, that is, less <>, if you want to sort data from large to small, there are many things involved here, which cannot be described in detail here.
It should also be noted that because of its internal order in map, it is ensured by the red and black trees, the time complexity of many function execution is log2n. If map functions can be used, STL algorithm can also implement this function. We recommend that you use the built-in Function Map, which is more efficient.
Next, let's talk about the features of map in space. Otherwise, it is estimated that you will sometimes be depressed when using it. Because each map data corresponds to a node on the red/black tree, when this node does not save your data, it occupies 16 bytes, a parent node pointer, left and right child pointer, and an enumeration value (marked as red and black, this is equivalent to the balance factor in the binary tree.) I think you should know that these areas are very memory-intensive ......
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/bat603/archive/2006/12/23/1456141.aspx