c++ 学习笔记:泛型编程

所有容器的共同操作

==和!=返回true或false

= 将某个容器复制个另一个容器

empty()在容器没有任何元素时返回true

size()容器内当前含有的元素

clear() 清除所有元素

begin()返回iterator,指向容器的第一个元素

end()返回iterator,指向容器最后一个元素的下一个位置

insert()  将一个或某个范围的元素插入容器

erase() 将容器内一个或某个范围的元素删除


使用序列式容器

序列式容器维护一组排列有序同类型的元素。

vector以一块儿连续内存存放元素,对vector进行随机存取颇有效率,如果将元素插入任意位置而不是vector末尾,效率将很低,同样删除末尾之外的任意元素,效率也很低。

vector比较适合数列。

list双向链接,非连续内存存储内容,可以执行向前或后退操作。每个元素包含三个字段:value、back指针(指向前一个元素)、front指针(指向下一个元素),在任意位置进行元素的插入或删除操作都很有效率。但如果进行随机存取操作,效率就不好了。

如果从文件中读取数据并排序,则每读一个数据便可能随机插入到数列中,可以选用list。

deque与vector类似都在连续内存中存放元素,但是deque对前端和末尾插入和删除元素都很有效率。

使用序列容器必须包含的头文件

#include <vector> 
#include <list> 
#include <deque>

有5种方式来定义序列容器:

1、创建空容器

list<string> slist; 
vector<int> ivec;

2、创建特定大小的容器,元素以默认值作为初值

list<int> ilist(1024); 
vector<string> svec(32);

3、创建特定大小的容器,并为每个元素赋特定初值

vector<int> ivec(10, -1); 
list<string> slist(16, "unassigned");

4、创建一个容器,用iterator区间的元素初始化容器

int ia[8] = { 1, 1, 2, 3, 5, 8, 13, 21 }; 
vector<int> fib(ia, ia+8); 

5、依据某容器创建新容器,复制原容器的元素作为新容器的初值

list<string> slist; // empty 
// fill slist ... 
list<string> slist2(slist); // copy of slist ...

两个特别的操作函数:

push_back():在容器末端插入一个元素

pop_back():删除末端元素

list和deque还提供了push_front()和pop_front()

pop_back()和pop_front()不返回被删除的元素值,可以用back()和front()函数得到。


容器除了通用的insert()插入函数外,还有其它四种变形。

iterator insert(iterator position, elemType value) 将value插入position之前,返回一个迭代器指向被插入元素;

list<int> ilist; 
// ... fill up ilist 
list<int>::iterator it = ilist.begin(); 
while (it != ilist.end()) 
if (*it >= ival) 
{ 
ilist.insert(it, ival); 
break; // exit loop 
} 
if (it == ilist.end()) 
ilist.push_back(ival);


void insert(iterator position, int count, elemType value) 在position之前插入count个元素,每个元素的值为value


string sval("Part Two"); 
list<string> slist; 
// ... fill slist ... 
list<string>::iterator it = find(slist.begin(), slist.end(), 
sval); 
slist.insert(it, 8, string("dummy"));

void insert(iterator1 position, iterator2 first, iterator2 last)在position之前插入first和last之间的元素

int ia1[7] = { 1, 1, 2, 3, 5, 55, 89 }; 
int ia2[4] = { 8, 13, 21, 34 }; 
list<int> elems(ia1, ia1+7); 
list<int>::iterator 
it = find(elems.begin(), elems.end(), 55); 
elems.insert(it, ia2, ia2 + 4); 

iterator insert(iterator position)在position之前插入元素,该元素的值为其所属类型的默认值。

pop_back()和pop_front()均属于容器擦除操作,erase()有另外两种变形

iterator erase(iterator posit)  删除posit所指元素,返回删除元素的下一位置

list<string>::iterator 
it = find(slist.begin(), slist.end(), str); 
slist.erase(it);

iterator erase(iterator first, iterator last) 删除从start开始但不包含last的元素。

list<string>::iterator 
first = slist.begin(), 
last = slist.end(); 
// it1: first element to erase, 
// it2: first element beyond elements to erase 
list<string>::iterator it1 = find(first, last, str); 
list<string>::iterator it2 = find(first, last, sval); 
slist.erase(it1, it2); 

list不支持iterator的偏移运算,因此不能写

// error: offset arithmetic is not 
// supported for list class 
slist.erase(it1, it1+num_tries);

使用泛型算法

使用泛型算法包含头文件

#include <algorithm> 

下列四种是我们常用的泛型搜寻算法:

find()搜寻无序集合中是否存在某值,若找到返回值得iterator否则返回iterator指向末尾元素

binary_serach()用于搜寻有序集合,找到返回true,未找到返回false

count()返回值相符的个数

search()比较容器内是否存在某子序列,若存在返回指向子序列的起始处的迭代器,否则指向容器末尾


binary_serach()要求其实施对象必须经过排序,如果不确定是否排序,可以将容器复制一份

vector<int> temp(vec.size());
copy(vec.begin(), vec.end(), temp.begin());
sort(temp.begin(), temp.end());  
return binary_search(temp.begin(), temp.end(), elem);

如何设计泛型算法

标准库为我们事先定义了一组function objects

Six arithmetic function objects: plus<type>, minus<type>, negate<type>
multiplies<type>, divides<type>, modulus<type> 
Six relational function objects: less<type>, less_equal<type>, greater<type>, 
greater_equal<type>, equal_to<type>, not_equal_to<type> 

Three logical function objects, using the &&, ||, and ! operators, respectively: 
logical_and<type>, logical_or<type>, and logical_not<type> 


头文件 

#include <functional> 

sort(vec.begin(), vec.end(), greater<int>()); 


使用map

map被定义为一对数值,通常key是字符串扮演索引的角色,另一个数值是value。

#include <map>  
#include <string>  
map<string,int> words;
输入key/value的最简单方式
words["vermeer"] = 1;
words[tword]会取出tword对应的value,如果tword不在map内,会被置于map内,其值为0,稍后出现,其值会加1.

map<string,int>::iterator it = words.begin();  
for (; it != words.end(); ++it)  
      cout << "key: "   << it->first  
           << "value: " << it->second << endl;

map有一个名为first的成员,对应于key,second对应value。

欲查询map内是否存在key,有三种方法:

第一种:

int count = 0;  
if (!(count = words[ "vermeer"]))  
        // vermeer not present 

缺点如果搜寻的key不存在于map内,则会将其加入map

第二种:利用map的find()函数

如果含有key,怎会返回iterator指向key/value形成的pair,反之返回end();

int count = 0;  
map<string,int>::iterator it;  
 
it = words.find("vermeer");  
if (it != words.end())  
     count = it->second; 

第三种利用map的count()函数,返回key在map中个数

int count = 0;  
string search_word("vermeer");  
 
if (words.count(search_word)) // ok: present ...  
     count = words[search_word];

任何一个key在map中只存储一份


使用set
set由一群keys组成,如果要判断某值是否存在于集合内可以用set
#include <set>
#include <string>
set<string> word_exclusion;
while (cin >> tword)
{
if (word_exclusion.count(tword))
// present in the set of excluded words?
// then skip the rest of this iteration
continue;

// ok: if here, not an excluded word
words[tword]++;
}


使用迭代器插入
如果先定义容器大小,可能会浪费空间,我们可以先定义个空容器,当有元素插入时再扩展。
对元素进行复制的泛型算法有 copy(), copy_backwards(), remove_copy(), replace_copy(), unique_copy()
标准程序库为我们提供了3个insertion adapters
back_inserter()
vector<int> result_vec;
unique_copy(ivec.begin(), ivec.end(),
back_inserter(result_vec));

inserter()
vector<string> svec_res;
unique_copy(svec.begin(), svec.end(),inserter(svec_res, svec_res.end()));

front_inserter()
list<int> ilist_clone;

copy(ilist.begin(), ilist.end(),
front_inserter(ilist_clone));

需包含的头文件是#include <iterator>

Using the iostream Iterators
标准程序库提供输入及输出用的iostream iterator 类, istream_iterator and ostream_iterator
需包含的头文件#include <iterator>

istream_iterator<string> is(cin);
istream_iterator<string> eof;
copy(is, eof, back_inserter(text));
ostream_iterator<string> os(cout, " ");
copy(text.begin(), text.end(), os);
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

int main()
{
istream_iterator<string> is(cin);
istream_iterator<string> eof;

vector<string> text;
copy(is, eof, back_inserter(text));

sort(text.begin(), text.end());

ostream_iterator<string> os(cout, " ");
copy(text.begin(), text.end(), os);
}

对文件操作类似


#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

int main()
{
ifstream in_file("as_you_like_it.txt");
ofstream out_file("as_you_like_it_sorted.txt");

if (! in_file || ! out_file)
{
cerr << "!!unable to open the necessary files.\n";
return -1;
}

istream_iterator<string> is(in_file);
istream_iterator<string> eof;

vector<string> text;
copy(is, eof, back_inserter(text));

sort(text.begin(), text.end());

ostream_iterator<string> os(out_file, " ");
copy(text.begin(), text.end(), os);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值