Boolan STL与泛型编程 第二周笔记

来源:互联网 发布:泰国直播软件 编辑:程序博客网 时间:2024/05/29 08:34

OOP(object-orientedprogramming)与GP(generic programming)

对于OOP,数据和操作放在一起,存放在类中。

对于GP,将数据和操作分开来。其操作和数据的连接方式如下图:

采用GP,容器和算法可以分开开发。算法通过迭代器确定操作范围,并通过迭代器取用容器中的元素。

为什么list不能使用全局sort进行排序?

因为全局sort中需要容器能够进行随机访问,而list只能进行顺序访问‘

 

类模版

基本的模版比较简单,有几个关键的地方如下图黄色部分:

 

函数模板

函数模版与类模版类似,如下图

这里的class与typename意思相同。

对于”<”的操作符重载,编译器会自己去寻找

对与函数模板使用时不需要写出数据类型,因为编译器会根据参数自己来进行推导

 

泛化与特化

在类模板中,我们泛化了数据类型,其数据类型可以是各种。但是或许我们会有一种想法,对于特定的某一种数据类型,我们想对其进行特殊的对待,这就是所谓的特化。

其语法示例如下:


偏特化/部分特化

其一,指的是模板有两个或两个以上参数,特化其中一个参数,称之为偏特化。

其二,是对于范围的偏特化,示例如下:

 

List探索

为了实现list的双向功能,每一个元素除了data之外应该还需要两个指针,分别指向前和后

除了vector,所有容器的迭代器都是一个类,用以实现类似智能指针的功能。

因为容器不是连续的,所以其迭代器不能如一个简单的指针一样进行++操作,从而访问下一个元素。

因为迭代器要模拟指针的操作,所以在迭代器的类中肯定要大量的操作符重载,用以模拟指针。

 

Vector容器内部含有三个指针,start、finish、end ofstorage,其扩充方式为两倍增长。

 

本周的作业为创建一个list容器,放置6个整形数值[0,1,30,20,10,0]

1.      从后向前打印出容器内的元素

2.      向list容器后面添加两个元素,并对容器内的值求和并打印

3.      打印链表的中间元素

4.      找到不为0的元素,复制到一个vector中并打印vector元素

 

思考:

1.      创建一个list,放置6个整形数值

这里采用列表初始化,list<int> wk{0,1,30,20,10,0}

2.      从后向前打印容器元素

考虑采用反向容器迭代器,wk.rbegin()/wk.rend(),

for (autoi = wk.crbegin(); i !=wk.crend(); ++i)

{

           cout << *i << endl;

        }

3.      向list容器后添加两个元素

wk.push_back

int n =0;

cout << "请输入需要添加的元素个数"<< endl;

cin >> n;

 

int xn;

int number_count=0;

cout << "请输入"<<n<<"个int型数值"<< endl;

while (cin>>xn)

{

           ++number_count;

           if (number_count < n)

           {

                    wk.push_back(xn);

                    cout << "请输入下一数"<< endl;

           }

           else if(number_count=n)

           {

                    wk.push_back(xn);

                    cout << "输入完毕"<< endl;

                    break;

           }

        }

4.      容器内求和

采用算法accumulate, int sum=accumulate(wk.begin(),wk.end(),0)

//求和并打印

cout<<"list容器中所有元素之和="

 << accumulate(wk.cbegin(), wk.cend(), 0)<< endl;

5.      打印链表的中间元素

List不支持随机访问,如何打印其中间元素呢?

List在添加了两个元素后,共有8个整形数值,打印中间元素意思是打印第4个和第5个元素?

那么智能顺序方位list,通过容器大小得出中间值的迭代器,再通过范围for打印中间值

 

在这一步的时候遇到一个很尴尬的问题,如代码所示,本来打算打印第4和第5个值

intn_count=0;

for (auto i = wk.cbegin();i!=wk.cend() ; ++i)

{

           ++n_count;

           cout << n_count << endl;

           if(n_count==wk.size()/2&&wk.size()%2==0)

           {

                    cout << "容器元素数量=" << wk.size() << "为偶数,中间元素有两个,分别是第"<< n_count << "个 " << *i <<

                    "和第"<<++n_count<<"个"<< *++i<<endl;

                    break;

           }

           else if(n_count == wk.size() / 2&& wk.size() % 2 != 0)

           {

                    cout << "容器元素数量="<<wk.size()<<"为奇数,中间元素有1个,为 "<< *++i << endl;

                    break;

           }

}

但是打印结果与预期不符合:

并没有按预期的先输出*i,再输出*++i.

经过思考,最终发现问题出在了endl上。Endl的左右是结束当前行并将缓冲区的内容刷到设备中。因为我是在语句的最终才有endl,所有在*i的内容实际刷写之前*i递增为了*++i,所以在最终刷写后,*i和*++i所指的内容其实都是*++i。

解决办法是在递增之前进行一次缓冲区刷写。

cout<< "容器元素数量= " << wk.size() << "为偶数,中间元素有两个,分别是第" << n_count << "个 "<< *i << flush;

                    cout<<"和第"<<++n_count<<"个"<< *++i<<endl;

6.      找到不为0的元素

方法一:循环判断,push_back到vector

方法二:找到list为0的元素删除,然后通过传递迭代器参数拷贝一个范围给vector

 

这里采用方法二:

list<int>temp = wk;

auto value_find = find(temp.cbegin(),temp.cend(), 0);

while (value_find!=temp.cend())

{

           temp.erase(value_find);

           value_find = find(temp.cbegin(),temp.cend(), 0);

}

vector<int> new_wk(temp.cbegin(),temp.cend());

for (auto x : new_wk)

           cout<< x << endl;


最终结果如下:


原创粉丝点击