博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Visual C++ 2008入门经典 第十章标准模板库(二)
阅读量:4555 次
发布时间:2019-06-08

本文共 12575 字,大约阅读时间需要 41 分钟。

//10.4 关联容器//关联容器(如map
)最重要的特性是无需搜索就可检索特定对像,关联容器内容T类型对像的位置由与对像一起提供的类型为K的键确定,因此只要提供适当的键就可以快速地检索任何对像,该键实际上是一个确定映射中的条目顺序的排序键//对于set
和nultiset
容器,对像作为它们自己的键,//10.4.1 使用映射容器//映射容器的模板在家
头文件中定义,当创建map
容器时,必须提供将使用的键的类型实参K,以及与键关联的对像类型T//map
phonebook;//虽然这里对要存储的映射中的键和对像都使用了类对像,但是映射中的键和关联对像也可以是任何基本类型//如int double, 或char//也可以创建一个映射容器,用另一个映射容器中的键/对像对序列来初始化://map
phonebook(iter1, iter2);//map
> phonebook;//1 存储对像//我们存储在映射中的对像总是模板类pait
的键/对像对,基中K是键的类型, T是与键关联的对像类型,//prit
类型是在
并没有文件中定义的,它被包括在
头文件中,因此如果正在使用映射,类型就会自动可用,//pair
entry = pait
(Person("Mel", "Gibson"), "213 324 6789");//pair
//pair
entry = make_pair(Person("Mel", "Gibson"), "213 345 56789");//map
phonebook;//typedef pair
Entry;//Entry entry1 = Entry(Person("Jack", "Jones"), "213 456 789456");//可以用insert()函数在映射中插入一个或多个对,例如,下面//phonebook.insert(entry1);//pair
::iterator, bool> checkpair;//checkpait = phonebook.insert(entry1);//if(checkpair.second){// cout<<"插和成功"<
first.showPerson();//phonebook[Person("Jack", "Jones")] = "1111111";// 2 访问对像//string number = phonebook[Person("Jack", "Jones")];/*string number;Person key = Person("Jack", "Jones");map
::iterator iter = phonebook.find(key);if(iter != phonebook.end()){ number = iter->second; cout<<"The number is "<
<
::size_type coutn = phonebook.erase(key);//if(count == 0){ //cout<<"Entry was not found."<
::iterator iter = phonebook.find(key);//iter = phonebook.erase(iter);//if(iter == phonebook.end()){// cout<<"end of the map reached."<
#include
#include
#include
#include
#include
using namespace std;class Person{public: Person(string first="", string second = "") { firstname = first; secondname = second; } bool operator<(const Person& p) const { if(secondname < p.secondname || (secondname == p.secondname && (firstname < p.firstname))) return true; else return false; } string getName() const{ return firstname +" "+secondname; }private: string firstname; string secondname;};Person getPerson(){ string first; string second; cout<<"输入姓:"<
& book){ pair
entry; string number; Person person = getPerson(); //要求输入Person信息 cout<<"请输入"<
<<"的电话号:"<
对像, //将entry插入到关联容器中去 //调用容器对像的insert()并存储pr中返回的对像 pair
::iterator, bool> pr = book.insert(entry); if(pr.second){ cout<<"插入成功!"; }else{ cout<<"用户已经存在"<
<<". the numbre is "<
second<
second; //pr返回的是一个迭代器,但这里返回的肯是包括所有相同值的元素的迭代器,所以用first取首个值的second }}//循环显示整个容器void listEntryes(map
& book){ if(book.empty()){ cout<<"book empty"<
::iterator iter; cout<
first.getName() <
<
second<
& book){ Person person = getPerson(); //提示用户输入信息 map
::const_iterator iter = book.find(person); //查找指定的键值对像 if(iter == book.end()){ cout<<"no entry found for"<
<
second<
& book){ Person person = getPerson(); map
::iterator iter = book.find(person); //先查找 if(iter == book.end()){ cout<<"没有找到指定元素"<
phonebook; //声明一个容器phonebook //映射的一个条目中的对像是含有电话号码的string,键是Person对像 char answer = 0; //声明一个字符变量 while(true){ cout<<"请输入你的记录(Y or N):"<
>answer; cin.ignore(); //调用cin的ignore()可以忽略下一个字符,使得接下来的输入可以正常工作 if(toupper(answer) == 'N'){ break; } if(toupper(answer) != 'Y'){ cout<<"请输入Y 或 N 进行操作"<
>answer; cin.ignore(); switch(answer){ case 'A': AddEntry(phonebook); break; case 'D': deleteEntry(phonebook); break; case 'G': getEntry(phonebook); break; case 'L': listEntryes(phonebook); break; case 'Q': return 0; break; default: cout<<"请输入合法值进行操作"<
multi/*Person person = Person("Jack", "Jones");nulitmap
::iterator iter = phonebook.lower_bound(person);if(iter == phonebook.end()){ cout<<"没有找到 "<
<
second<
#include
#include
#include
#include
#include
using namespace std;class Person{public: Person(string first="", string second = "") { firstname = first; secondname = second; } bool operator<(const Person& p) const { if(secondname < p.secondname || (secondname == p.secondname && (firstname < p.firstname))) return true; else return false; } string getName() const{ return firstname +" "+secondname; }private: string firstname; string secondname;};Person getPerson(){ string first; string second; cout<<"输入姓:"<
& book){ pair
entry; string number; Person person = getPerson(); //要求输入Person信息 cout<<"请输入"<
<<"的电话号:"<
对像, //entry = pair
; entry = pair
(person, number); //prit
类型是在
并没有文件中定义的,它被包括在
头文件中,因此如果正在使用映射,类型就会自动可用, //pair
entry = pait
(Person("Mel", "Gibson"), "213 324 6789"); //pair
//pair
entry = make_pair(Person("Mel", "Gibson"), "213 345 56789"); //map
phonebook; //typedef pair
Entry; //Entry entry1 = Entry(Person("Jack", "Jones"), "213 456 789456"); //checkpait = phonebook.insert(entry1); //将entry插入到关联容器中去 //调用容器对像的insert()并存储pr中返回的对像 //pair
::iterator pr = book.insert(entry); //插入不成功,失败在这里 //pair
::iterator, bool> pr = book.insert(entry); if(pr.second){ cout<<"插入成功!"; }else{ cout<<"用户已经存在"<
<<". the numbre is "<
second<
second; //pr返回的是一个迭代器,但这里返回的肯是包括所有相同值的元素的迭代器,所以用first取首个值的second }}//循环显示整个容器void listEntryes(multimap
& book){ if(book.empty()){ cout<<"book empty"<
::iterator iter; cout<
first.getName() <
<
second<
& book){ Person person = getPerson(); //提示用户输入信息 multimap
::const_iterator iter = book.find(person); //查找指定的键值对像 if(iter == book.end()){ cout<<"no entry found for"<
<
second<
& book){ Person person = getPerson(); multimap
::iterator iter = book.find(person); //先查找 if(iter == book.end()){ cout<<"没有找到指定元素"<
second<
phonebook; //声明一个容器phonebook //映射的一个条目中的对像是含有电话号码的string,键是Person对像 char answer = 0; //声明一个字符变量 while(true){ cout<<"请输入你的记录(Y or N):"<
>answer; cin.ignore(); //调用cin的ignore()可以忽略下一个字符,使得接下来的输入可以正常工作 if(toupper(answer) == 'N'){ break; } if(toupper(answer) != 'Y'){ cout<<"请输入Y 或 N 进行操作"<
>answer; cin.ignore(); switch(answer){ case 'A': AddEntry(phonebook); break; case 'D': deleteEntry(phonebook); break; case 'G': getEntry(phonebook); break; case 'L': listEntryes(phonebook); break; case 'Q': return 0; break; default: cout<<"请输入合法值进行操作"<
头文件定义迭代器的几个模板将数据从源传到目的地,流迭代器作为指向输入或输出流的指针,它们可以用来在流和任何使用迭代器的源或目的地之间传输数据,如算法//插入迭代器可以将数据传输给一个其本序列容器//
头文件定义两个流迭代器模板,基中istream_iterator
用于输入流//ostream_iterator
用于输出流//头文件还定义了三个插入模板: inserter
, back_inserter
front_inserter
//10.5.1 使用输入流迭代器//创建输入流迭代器//istream_iterator
numbersInput(cin);//istream_iterator
< numbersEnd;//我们有一对迭代器,定义cin中一个int类型的值的序列,可以用这些迭代器将cin中的值加载到vector
容器中/*vector
numbres;istream_iterator
numbresInput(cin), numbresEnd;cout<<"开始输入数值"<
begin(input), end;cout<
<
#include
#include
#include
#include
#include
#include
using namespace std;int _tmain(int argc, _TCHAR* argv[]){ typedef map
::const_iterator Iter; map
words; //这个容器用string类型的单词作为键来存储int类型的每个单词的个数,当我们用流迭代器从输入流中读取时,用它会使每个单词的个数累计更容易 cout<<"请输入数字值以空格分割开退出请按A+Z"<
begin(cin); std::istream_iterator
end; while(begin != end){ words[*begin++]++; //递增和存储一个计算值 //在循环内我们用映射容器的下标运算符将单词的个数存储为键,注意,映射的下标运算符的实参是键,表达式*begin访问一个单词,表达式*begin++在访问单词后递增迭代器 //在第一次读取一个单词时,它不会在映射中,因此表达式words[*begin++]将新条目的个数存储为默认值0 //并将begin迭代器递增到下一个单词,准备下一个循环迭代,整个表达式[*begin++]++会递增条目的个数,不管它是不是新条目,因此,现有条目只会使个数递增,而新条目会被创建,然后它的个数从0递增到1 //还是没看懂这段 } cout<<"现在开始输出:"<
second<<" "<
first<
, deque
和list
中的任何一个添加新元素的迭代器//back_inserter
在类型T的容器末尾插入元素//front_inserter
在类型T的容器开头插入元素//inserter
在类型T的容器内从指定位置开始插入元素//vector
numbres;//front_inserter
> iter(numbres);//*iter = 99;//inserter
> iter_anywhere(numbres,numbres.begin());/*for(int i=0; i<100; i++){ *iter_anywhere = i+1;}list
values;istream_iterator
input(cin), input_endl;copy(input, input_end, back_inserter
>(values))*///10.5.3 使用输出流迭代器//ostream_iterator
out(cout);//该模板的类型实参int指定要处理的数据类型,构造函数实参cout指定将作为数据的目的地的流//int data[]= {1, 2, 3, 4, 5, 6, 7, 8, 9};//vector
numbres(data, data+9);//copy(numbres.begin(), numbres.end(), out);//在
头文件中定义的copy()算法复制由第三个实参指定的输出迭代器的对像序列(由第二个实参指定)//ostream_iterator
out(cout,", ");//这个构造函数的第二个实参是一个字符串,作为输出值的分隔符,如果用这个迭代器作为前面代码版段中copy()函数的第三个实参/*#include "stdafx.h"#include
#include
#include
#include
using namespace std;int _tmain(int argc, _TCHAR* argv[]){ vector
numbres; cout<<"请输入数值,退出请按(Ctrl+Z):"<
input(cin), input_end; //创建两个输入流迭代器,用来从标准输入流input和input_end中读取int类型的值 ostream_iterator
out(cout, " "); //创建一个输入流迭代器,将int类型的值传输给标准输出流,跟在每个输出值后面的分隔符是一个空格 copy(input, input_end, back_inserter
>(numbres)); //我们通过两个输入流迭代器input和input_end指定复制操作的数据源,复制操作的目的地是numbres容器的后端插入迭代器 //因此,复制操作会通过后端插入迭代器将cin中的数据值传输到numbres容器中 cout<<"输入的数据如下:"<
头文件定义了一个可扩展的模板集合,用来创建可用于算法和容器的函数对像,//less
创建一个二元谓词,表示T类型之间的
<运算,例如:less>
()定义一个比较string类型对像的函数对像//less_equal
创建一个二元谓词,表示T类型对像之间的<=运算,例如:less_equal
()定义一个比较double类型对像的函数对像//equal
创建一个二元谓词,表示T类型对像之间的==运算//not_equal
创建一个二元谓词,表示T类型对像之间的!=运算//geater_equal
创建一个二元谓词,表示T类型对像之间的>=运算//greater
创建一个二元谓词,表示T类型对像之间的>运算//not2
创建一个二元谓词,它是B类型的二元谓词的负值,例如,not2(less
)创建一个二元谓词来比较int类型的对像//如果左操作数不小于右操作数,则返回true//下面的代码是用not2
模板来定义用于sort()算法的二元谓词//sort(v.begin(), v.end(), not2(greater
()));//
头文件还定义对元素进行算术运算的函数对像//plus
计算两个T类型元素的和//minus
通过从第一个操作数中减去第二个操作数计算两个T类型元素之间的差//multiplies
计算两个T类型元素的积//divides
用第一个T类型操作数除以第二个T类型操作数//modulus
计算第一个T类型操作数除以第二个操作数后的余数//negate
返回它的T类型操作数的负值//10.7 关于算法的更多内容//
头文件中的这些算法主要用来处理数组中的数值,//
头文件中的算法大多用搜索,排序和合并迭代器指定的对像序列//10.7.1 fill()//fill(ForwardIterator begin, ForwardIterator end, const Type& value);//它会用值填充由迭代器begin()和end()指定的元素//fill(v.begin(), v.begin()+9, "invalid");//10.7.2 replace()//replace(ForwardIterator begin, ForwardIterator end, const Type& oldValue, const Type& newValue);//函分析begin()和end()指定的每个元素,并用newValue替换出现的每个oldValue//replace(v.begin(), v.end(), "yes", "no");//replace()函数也会使用指针//char str[] = "A nod is as good as a wink to a blind hors.";//replace(str, str+strlen(str), 'o', '*');//10.7.3 find();//find(InputIterator begin, InputIterator end, const Type& value);//搜索由首次出现在value的前两个实参指定的序列//vector
::itertor iter = find(v.begin(), v.end(), 21)//find()算法反复查找出现的所有给定值//vector
#include
#include
#include
#include
using namespace std;int _tmain(int argc, _TCHAR* argv[]){ ouble values[] = {2.5, -3.5, 4.5, -5.5, 6.5, -7.5}; vector
data(values, values+6); transform(data.begin(), data.end(), data.begin(), negate
()); vector
::iterator iter = data.begin(); int i = 0; while(iter != data.end()) { i++; //cout<<"i="<
<
#include
#include
#include
#include
using namespace std;int _tmain(int argc, _TCHAR* argv[]){ double values[] = {2.5, -3.5, 4.5, -5.5, 6.5, -7.5}; vector
data(values, values+6); vector
squares(data.size()); transform(data.begin(), data.end(), data.begin(), squares.begin(), multiplies
()); ostream_iterator
out(cout, " "); copy(squares.begin(), squares.end(), out); system("pause"); return 0;}*///10.8 C++/CLI程序中的STL//STL/CLR包含在cliext命名空内,因此所有STL名称都用cliext而不是std限定//10.8.1 STL/CLR容器/*T (const T% t){}//构造函数T% operator=(const T% t){}//重载=运算符~T(){ }//析构函数*///这些容器操作也要求定义无实参构造函数和operator==function,当容器存储对像而不是句柄时,如果需要为容器中的元素分配空格,就可以要用到无实参构造函数,如果在一个关联容器(如集合或映射)中存储引用类型的句柄或者值类型,它们至少必须重载一个运算符--默认要求重载operator<()//10.8.2 使用序列容器//本地C++的STL提供的所有序列容器也可用于STL/CLR,STL/CLR实现本地STL容器支持的所有操作,只是使用C++/CLI类型时可能会出现一些区别,下面通过一些示例来介绍这些区别/*ref class Person{public: Person():firstname(""), secondname(""){} Person(String^ first, String^ second):firstname(first), secondname(second){} virtual String^ ToString() override { return firstname+L" "+secondname; }private: String^ firstname; String^ secondname;};*///我们只在矢量中存储Person对像的句柄,因此不需要实现复制构造函数或赋值运算符,//ToString()函数重写了继承自类Object的版本,并且出于输出的目的/*#include "stdafx.h"#include
#include
//using namespace System;using namespace cliext;ref class Person{public: Person():firstname(""), secondname(""){} Person(string^ first, string^ second):firstname(first), secondname(second){} virtual String^ ToString() override { return firstname+L" "+secondname; }private: string^ firstname; string^ secondname;};int _tmain(int argc, _TCHAR* argv[]){ system("pause"); return 0;}*///10.8.3 使用关联容器//STL/CLR中的甩的关联容器的使用方式基本上与等价的本地STL容器相同,但是有一个重要的小区别,通常在处理对象的表示方式方面//首先,我们存储在类型映射中的元素的类型//map
//在本地STL中的类型pair
,但是在STL/CLR映射容器中它是类型map
::value_type,//它是一个数值类型,这暗示了我们不再能用make_pair()函在STL/CLR中创建映射条目,取而代之的是使用map
类中定义的静态make_value()函数//第二,在map
中插入一个元素的insert()函数对于本地STL容器返回一个类型pair
::iterator, bool>类型的值,而对于STL/CLR map
容器,insert()函数返回下面的这个类型的值//map
::pair_iter_bool//它是一个引用类型,类型map
::pair_iter_bool的对像有两个公有字段,first和second//first是下面类型的迭代器的一个句柄//map
::iterator^//second的类型为bool,如果second的值为true,那么first就指向新插入的元素,否则它指向映射中已经存在的具有相同键的元素//10.9 小结//STL和STL/CLR功能,包括容器,迭代器,算法和函数对像的模板//容器是一个存储和组织其他对像的类,序列容器用一个序列(如数组)存储对像,关联容器存储是键/对像对的元素,其中键确定对存储在容器中的何处//迭代器是行为与指针相似的对像,对中的迭代器用来通过一个半开放的间隔定义一个对像集合,其中第一个迭代器指向系列中的第一个对像,第二个迭代器指向系列中最后一个对像的下一个位置//流迭代器是允许我们访问或修改流中的内容的迭代器//迭代器有四大类,输入和输出迭代器,前向迭代器,双向迭代器和随机访问迭代器,迭代器这几类中每一类都提供了比上一类更多的功能,因此输入和输出迭代器提供的功能性最小,随机访问迭代器提供的功能性最大//算法是在一对迭代器指定的一个对像序列上操作的模板函数//函数对像是重载()运算符(通过在类中实现函数operator()())的类型的对像,STL和STL/CLR定义用于容器和算法的广泛类型的标准迭代器,我们也可以写自己的类来定义函数对像)

  

转载于:https://www.cnblogs.com/xiangxiaodong/archive/2012/11/18/2776007.html

你可能感兴趣的文章
2019百度之星初赛二 1001 度度熊与数字(因子问题)
查看>>
2019百度之星初赛三 1001最短路1(异或)
查看>>
P3372 【模板】线段树 1 (区间查询)
查看>>
What Are You Talking About HDU - 1075(字典树)
查看>>
Phone List HDU - 1671(字典树)
查看>>
I Hate It HDU - 1754(线段树找区间最大值)
查看>>
牛客假日团队赛11 H 过河卒(路径条数dp)
查看>>
P3374 树状数组 1(单点修改求和)
查看>>
敌兵布阵 HDU - 1166 (线段树单点修改)
查看>>
WIN10安装.net报0x800F081F解决方法
查看>>
Win10删除或是不显示快速访问中最近使用文件记录
查看>>
Dell T30解决报Alert! Cover was previously removed.
查看>>
win10开机后将存在多个系统选择,改为直接进入系统无需选择
查看>>
word生成目录的pdf
查看>>
VMware网络配置三种网络模式(桥接、NAT、Host-only)
查看>>
SVN 执行cleanup报错:Cleanup failed to process the following paths
查看>>
linux-centos7.6设置固定IP网络方法
查看>>
Visual Studio 2013进行python开发(一)---开发环境配置
查看>>
Visual Studio 2013进行Python开发(二)---python连接sql server数据库
查看>>
Visual Studio 2013进行Python开发(三)--多表联合查询
查看>>