小言_互联网的博客

C++primer-学习心得-第十章-泛型算法

529人阅读  评论(0)

C++primer-学习心得-第十章-泛型算法

上个章节学习了各种顺序容器,但顺序只定义了很少的操作,我们能做的事情还很少,我们希望能做更多的事情如:查找特定元素、替换或删除一个特定值、重排元素顺序等。标准库没有给每个容器定义相关的成员函数来实现这些操作,但定义了一组泛型算法:算法:实现了一些经典算法的公共接口(如排序和搜索),泛型:可以用于不同类型的元素和多种容器类型(不仅包括标准库类型还包括内置的数组类型),还能用于其他类型的序列。

10.1 概述

大多数算法都定义在头文件algorithm中,标准库还在头文件numeric中定义了一组数值泛型算法。为了说明算法是如何用于不同容器的,我们以find为例,find的工作是在一个未排序的元素序列中查找一个特定元素。概念上find将执行如下步骤。

  1. 访问序列中的首元素
  2. 比较此元素与我们要查找的值
  3. 如果此值与我们要查找的值匹配,find返回表示此元素的值
  4. 否则,find前进到下一个元素,重复步骤2、3
  5. 如果到达序列尾,find应停止
  6. 如果find到达序列末尾,它应该返回一个指出元素未找到的值,这个值的类型应与步骤3中返回值的类型相容。

这些步骤都不依赖容器保存的元素类型,因此只要有一个迭代器可用来访问元素,find就完全不依赖于容器类型。

练习10.1

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>

using namespace std;
int main() {
	vector<int> vi = { 1,2,3,2,1,2,3,2,3,22,4,52,3,4,5,67,78,76,6,5,5,4 };
	auto test = count(vi.cbegin(), vi.cend(), 2);
	cout << test << endl;
}

练习10.2

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
using namespace std;
int main() {
	list<string>ls = {"a","a","a","reo","reoreo","b","b"};
	auto a=count(ls.cbegin(), ls.cend(), "a");
	cout << a << endl;
}

10.2 初识泛型算法

标准库提供了超过一百种算法,有容器类似地这些算法有一致的结构,所以我从理解结构入手更好一点。除了少数例外,标准库算法都对一个范围内的元素(输入范围)进行操作,这个范围通常由一对迭代器表示。通常他们使用范围内的元素的方式是不同的,如是否读取元素,改变元素,重排元素顺序。

1. 只读算法

如前面接触的find和count,不会改变元素。另一个只读算法是accumulate,定义在头文件numeric中。

练习10.3

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
int main() {
	vector<int>vi = { 1,2,3,23,23,12,12,23,32,3,423,3,2,21,2,3,4,67,8,9,6 };
	auto sum = accumulate(vi.begin(), vi.end(), 0);
	cout << sum << endl;
}

另一个只读算法是equal,

equal(r1.cbegin(),r1.cend(),r2.cbegin());

2.写容器元素的算法

如fill将给定值赋予给输入范围的每个元素。fill_n接受一个单迭代器,一个计数值和一个值,将定值赋予给迭代器指向的元素开始的n个值。

back_insert

插入迭代器:向容器中添加元素的迭代器。而back_insert定义在头文件iterator中,它接受一个指向容器的引用返回一个与容器绑定的插入迭代器。

vector<int>vec;
auto it=back_insert(vec);
*it=22;
fill_n(back_insert(vec),10,0);

copy算法

int a[]={0,1,2,3,4,5};
int a2[sizeof(a)/sizeof(*a)];
auto ret=copy(begin(a),end(a),a2);

练习10.6

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
int main() {
	vector<int>vi = { 1,2,3,23,23,12,12,23,32,3,423,3,2,21,2,3,4,67,8,9,6 };
	fill_n(vi.begin(), vi.size(), 0);
	for (auto c : vi) {
		cout << c << endl;
	}
}

3.重排容器元素的算法

sort,unique

练习10.9

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
void elimdups(vector<int>&vi) {
	sort(vi.begin(), vi.end());
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
int main() {
	vector<int>vi = { 1,2,3,23,23,12,12,23,32,3,423,3,2,21,2,3,4,67,8,9,6 };
	elimdups(vi);
	for (auto c : vi) {
		cout << c << endl;
	}
}

10.3定制操作

1.向算法传递函数

谓词:是一个可调用的表达式,其返回结果是一个可用作条件的值。有两类谓词:一元谓词(只接受单一参数)、二元谓词(两个参数)。接受谓词参数的算法对输入序列中的元素调用谓词,因此元素类型必须能转换为谓词的参数类型。如sort接受一个二元谓词参数。(JavaScript也有类似的机制)

bool isShorter(const string &s1,const string &s2){
return s1.size()<s2.size();
}
sort(words.begin(),words.end(),isShorter);

另外还有stable_sort保存等长元素间的字典序。

练习10.11

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
bool isShorter(const int& v1,const int& v2) { return v1 > v2; }//二元谓语
void elimdups(vector<int>&vi) {
	sort(vi.begin(), vi.end(),isShorter);
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
int main() {
	vector<int>vi = { 1,2,3,23,23,12,12,23,32,3,423,3,2,21,2,3,4,67,8,9,6 };
	elimdups(vi);
	for (auto c : vi) {
		cout << c << endl;
	}
}

练习10.12

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
class Sales_data {//偷个懒就创建一个简单的Sales_data类
public:
	string getisbn() { return bookNo; }
	Sales_data(string s, unsigned u, double d) :bookNo(s), sold(u), revenue(d) {}
	Sales_data() :Sales_data(" ", 0, 0.0) {}
	Sales_data(string s) :Sales_data(s, 0, 0.0) {}
private:
	string bookNo;
	unsigned sold;
	double revenue;
};
bool isShorter(Sales_data& s1,  Sales_data& s2) {
	return s1.getisbn() > s2.getisbn();
}
void elimdups(vector<Sales_data>&vi) {
	sort(vi.begin(), vi.end(),isShorter);
	//auto end_u = unique(vi.begin(), vi.end());
	//vi.erase(end_u, vi.end());
}
int main() {
	vector<Sales_data>vi;
	vi.emplace_back("ssss");
	vi.emplace_back("asdf", 12, 22);
	vi.emplace_back("afasd", 12, 22);
	vi.emplace_back("dsfa", 23, 223);
	elimdups(vi);
	for (auto it = vi.begin(); it != vi.end();it++) {
		cout << it->getisbn() << endl;
	}
}

练习10.13

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;

bool sizes(string s) {
	return s.size()<5?true:false;
}
int main() {
	vector<string> vs = { "asdf","afdfasd","q3qwer","asd","dfg" };
	auto end_p=partition(vs.begin(), vs.end(), sizes);
	if (end_p == vs.end()) {
		cout << "没有长度大于等于5的字符串" << endl;
	}
	else {
		for (auto it = end_p; it != vs.end(); it++) {
			cout << *it << endl;
		}
	}
}

2.lambda表达式

一个lambda表达式表示一个可调用的代码单元。可以理解未未命名的内联函数。与函数类似,一个lambda具有一个返回类型、一个参数列表和一个函数体。但不同的是它可以定义在函数内部。

[capture list](parameter list)->return type{function body}

练习10.14

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;

bool sizes(string s) {
	return s.size()<5?true:false;
}
int main() {
	int a = 10, b = 20;
	auto c = [](int a,int b) {return a + b; };
	cout<<c(a,b)<<endl;
}

练习10.15

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;

bool sizes(string s) {
	return s.size()<5;
}
int main() {
	int a = 10, b = 20;
	auto c = [a](int b) {return a + b; };
	cout<<c(b)<<endl;
}

练习10.17

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
class Sales_data {//偷个懒就创建一个简单的Sales_data类
public:
	string getisbn() { return bookNo; }
	Sales_data(string s, unsigned u, double d) :bookNo(s), sold(u), revenue(d) {}
	Sales_data() :Sales_data(" ", 0, 0.0) {}
	Sales_data(string s) :Sales_data(s, 0, 0.0) {}
private:
	string bookNo;
	unsigned sold;
	double revenue;
};
void elimdups(vector<Sales_data>& vi) {
	sort(vi.begin(), vi.end(), [](Sales_data& s1, Sales_data& s2) {
		return s1.getisbn() > s2.getisbn();
		});
	//auto end_u = unique(vi.begin(), vi.end());
	//vi.erase(end_u, vi.end());
}
int main() {
	vector<Sales_data>vi;
	vi.emplace_back("ssss");
	vi.emplace_back("asdf", 12, 22);
	vi.emplace_back("afasd", 12, 22);
	vi.emplace_back("dsfa", 23, 223);
	elimdups(vi);
	for (auto it = vi.begin(); it != vi.end(); it++) {
		cout << it->getisbn() << endl;
	}
}

练习10.18

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;

void elimdups(vector<string>& vi) {
	sort(vi.begin(), vi.end());
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
void biggies(vector<string>& words, vector<string>::size_type sz) {
	elimdups(words);
	auto end_p = partition(words.begin(), words.end(), [sz](const string s) {return s.size() < sz; });
	for (auto it = end_p; it != words.end(); it++) {
		cout << *it << endl;
	}
}
int main() {
	vector<string>words = { "reoreo","The world","flandre","a","b","sss","sasdf","aaa" };
	vector<string>::size_type sz = 6;
	biggies(words, sz);
}

练习10.19

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;

void elimdups(vector<string>& vi) {
	sort(vi.begin(), vi.end());
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
void biggies(vector<string>& words, vector<string>::size_type sz) {
	elimdups(words);
	auto end_p = stable_partition(words.begin(), words.end(), [sz](const string s) {return s.size() < sz; });
	for (auto it = end_p; it != words.end(); it++) {
		cout << *it << endl;
	}
}
int main() {
	vector<string>words = { "reoreo","The world","flandre","a","b","sss","sasdf","aaa" };
	vector<string>::size_type sz = 6;
	biggies(words, sz);
}

3.lambda的捕获和返回

  • []
  • [names]
  • [&]:引用捕获
  • [=]:值捕获
  • [&,identifier_list]
  • [=,identifier_list]

对于一个值被拷贝的变量可以加关键字mutable来允许改变被捕获的值。(值捕获+mutable–>引用捕获)

当我们需要为lambda表达式定义返回类型时必须使用尾置返回类型。

练习10.20

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;

void elimdups(vector<string>& vi) {
	sort(vi.begin(), vi.end());
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
void biggies(vector<string>& words, vector<string>::size_type sz) {
	elimdups(words);
	auto counts = count_if(words.begin(), words.end(), [sz](const string s) {return s.size() >= sz; });
	cout << counts << endl;
}
int main() {
	vector<string>words = { "reoreo","The world","flandre","a","b","sss","sasdf","aaa" };
	vector<string>::size_type sz = 6;
	biggies(words, sz);
}

练习10.21

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;


int main() {
	int a = 10;
	auto f = [&]() {
		if (a == 0) {
			return true;
		}
		else {
			while (a > 0)
				--a;
			return false;
		}

		};
	cout << f() << endl;
}

4.参数绑定

在我们这里lambda表达式相比较谓词具有的一个决定性优势就是它可以捕获变量,而谓词定义的时候参数列表是受限的。但如果我们希望能在能多地方使用,lambda表达式的话就需要重复的编写,这时函数就更具有优势了。那么有没有什么办法解决参数捕获的问题呢,方法是有的。

我们可以使用名为bind 的标准库函数,它定义在头文件functional中。一般形式为

auto newCallable=bind(callable,arg_list);

如一元谓词check_size

bool check_size(const string &s,string::size_type sz){
return s.size()>=sz;}
auto wc=find_if(words.begin(),words.end(),bind(check_size,_1,sz));

_n为占位符,定义在名为placeholders的命名空间中,而这个命名空间又定义在std中。可以通过声明:

using namespace std::placeholders;

来使得其中的名字可用。

练习10.22

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
#include<functional>
using namespace std;
using namespace placeholders;
void elimdups(vector<string>& vi) {
	sort(vi.begin(), vi.end());
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
bool check_size(const string& s, vector<string>::size_type sz) {
	return s.size() >= sz;
}
void biggies(vector<string>& words, vector<string>::size_type sz) {
	elimdups(words);
	auto counts = count_if(words.begin(), words.end(), bind(check_size,_1,sz));
	cout << counts << endl;
}
int main() {
	vector<string>words = { "reoreo","The world","flandre","a","b","sss","sasdf","aaa" };
	vector<string>::size_type sz = 6;
	biggies(words, sz);
}

练习10.23

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
#include<functional>
using namespace std;
using namespace placeholders;

bool check_size(const int& i, string s) {
	return i >s.size();
}
int main() {
	vector<int>vi = { 1,2,3,4,5,6,7,8,9,10 };
	string str = "asdfsadf";
	auto a = find_if(vi.begin(), vi.end(), bind(check_size, _1, str));
	cout << *a << endl;
}

练习10.24

#include<vector>
#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
#include<functional>
using namespace std;
using namespace placeholders;
void elimdups(vector<string>& vi) {
	sort(vi.begin(), vi.end());
	auto end_u = unique(vi.begin(), vi.end());
	vi.erase(end_u, vi.end());
}
bool check_size(const string &s,vector<string>::size_type sz) {return s.size() < sz; }
void biggies(vector<string>& words, vector<string>::size_type sz) {
	elimdups(words);
	auto end_p = partition(words.begin(), words.end(), bind(check_size,_1,sz));
	for (auto it = end_p; it != words.end(); it++) {
		cout << *it << endl;
	}
}
int main() {
	vector<string>words = { "reoreo","The world","flandre","a","b","sss","sasdf","aaa" };
	vector<string>::size_type sz = 6;
	biggies(words, sz);
}

另外要注意的是用bind绑定参数的方式都是以拷贝的形式,相当于值传递的lambda函数,那么如果需要改变绑定的参数时,需要用到标准库函数ref或者cref。

10.4 再探迭代器

迭代器可以分为以下几类:

  • 插入迭代器
  • 流迭代器
  • 反向迭代器
  • 移动迭代器

1.插入迭代器

有三种类型的插入迭代器

  • back_inserter:创建一个使用push_back的迭代器
  • front_inserter:创建一个使用front_back的迭代器
  • inserter:创建一个使用insert的迭代器。接受两个参数

练习10.27

#include<vector>
#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
#include<functional>
using namespace std;
using namespace placeholders;

int main() {
	vector<string>words = { "reoreo","The world","flandre","a","b","sss","sasdf","aaa" ,"aaa","reoreo","reoreo"};
	list<string>ls;
	
	unique_copy(words.begin(), words.end(), back_inserter(ls));
	vector<string>::size_type sz = 6;
	//biggies(words, sz);
	for (auto& c : ls)
		cout << c << endl;
}

练习10.28

#include<vector>
#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
#include<deque>
#include<forward_list>
#include<functional>
#include<iterator>
using namespace std;
using namespace placeholders;

int main() {
	vector<int>vi = { 1,2,3,4,5,6,7,8,9 };
	list<int>li;
	deque<int>di;
	forward_list<int>fi;
	unique_copy(vi.begin(), vi.end(), back_inserter(li));
	unique_copy(vi.begin(), vi.end(), front_inserter(fi));//forward_list没有push_back
	unique_copy(vi.begin(), vi.end(), back_inserter(di));
	vector<string>::size_type sz = 6;
	//biggies(words, sz);
	cout << "list" << endl;
	for (auto& c : li)
		cout << c << endl;
	cout << "forward_lsit" << endl;
	for (auto& c : fi)
		cout << c << endl;
	cout << "deque" << endl;
	for (auto& c : di)
		cout << c << endl;
}

2. iostream 迭代器

istream_iterator读取输入流

  • istream_iterator<T> in(is);
  • istream_iterator<T>end;
  • in1==in2
  • in1!=in2
  • *in
  • in->men
  • ++in,in++

ostream_iterator读取输出流

  • ostream_iterator<T>out(os)
  • ostream_iterator<T>(os,d)
  • out=val
  • *out,++out,out++

练习10.29

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
using namespace std;
int main() {
	ifstream is("源.cpp");
	istream_iterator<string>in(is);
	istream_iterator<string> ends;
	vector<string> file_text;
	for (auto it = in; it != ends; it++) {
		file_text.push_back(*it);
	}
	is.close();
	for (auto c : file_text)
		cout << c << endl;
}

练习10.30

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	istream_iterator<int>in(cin);
	istream_iterator<int> ends;
	vector<int> file_text;
	for (auto it = in; it != ends; it++) {
		file_text.push_back(*it);
	}
	sort(file_text.begin(), file_text.end());
	ostream_iterator<int> out(cout, "\n");
	copy(file_text.begin(), file_text.end(), out);
	cout << endl;
}

练习10.31

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>

using namespace std;
int main() {
	istream_iterator<int>in(cin);
	istream_iterator<int> ends;
	vector<int> file_text;
	vector<int>ff;

	for (auto it = in; it != ends; it++) {
		file_text.push_back(*it);
	}
	sort(file_text.begin(), file_text.end());
	auto end_u = unique_copy(file_text.begin(), file_text.end(), back_inserter(ff));
	//ff.erase(end_u, ff.end());
	ostream_iterator<int> out(cout, "\n");
	copy(ff.begin(), ff.end(), out);
	cout << endl;
}

练习10.32

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>
#include<numeric>
using namespace std;
class Sales_data {//偷个懒就创建一个简单的Sales_data类
public:
	string getisbn() { return bookNo; }
	double getrevenue() { return revenue; }
	Sales_data(string s, unsigned u, double d) :bookNo(s), sold(u), revenue(d) {}
	Sales_data() :Sales_data(" ", 0, 0.0) {}
	Sales_data(string s) :Sales_data(s, 0, 0.0) {}
private:
	string bookNo;
	unsigned sold;
	double revenue;
};
bool isShorter(Sales_data& s1, Sales_data& s2) {
	return s1.getisbn() > s2.getisbn();
}
void elimdups(vector<Sales_data>& vi) {
	sort(vi.begin(), vi.end(), isShorter);
	//auto end_u = unique(vi.begin(), vi.end());
	//vi.erase(end_u, vi.end());
}
int main() {
	vector<Sales_data>vi;
	vi.emplace_back("ssss");
	vi.emplace_back("asdf", 12, 22);
	vi.emplace_back("afasd", 12, 22);
	vi.emplace_back("dsfa", 23, 223);
	elimdups(vi);
	vector<double>re;
	for (auto it = vi.begin(); it != vi.end(); it++) {
		//cout << it->getisbn() << endl;
		re.push_back(it->getrevenue());
	}
	auto sum = accumulate(re.begin(), re.end(), 0.0);
	cout << sum << endl;
}

练习10.33

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>
#include<numeric>
#include<fstream>

using namespace std;
void f(string f1, string f2, string f3) {
	ifstream in(f1);
	istream_iterator<int> ins(in);
	istream_iterator<int> endi;
	ofstream o1, o2;
	o1.open(f2);
	o2.open(f3);
	ostream_iterator<int>oo1(o1, "\n "),oo2(o2," ");
	for (auto it = ins; it != endi; it++) {
		cout << *it << endl;
		if (*it % 2)
			oo2 = *it;
		else
			oo1 = *it;
	}
}

int main() {
	ofstream out;
	string ff = "num.txt";
	out.open(ff);
	int i;
	ostream_iterator<int> outs(out,"\n");
	istream_iterator<int> in(cin);
	istream_iterator<int>endi;
	while (in != endi) {
		*outs++=*in++;
	}
		
	out.close();
	f(ff, "a.txt", "b.txt");
}

3.反向迭代器

练习10.34

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>

using namespace std;
int main() {
	vector<int> ff = { 1,2,3,4,5,6,7,8,9 };
	ostream_iterator<int> out(cout, "\n");
	copy(ff.rbegin(), ff.rend(), out);
	cout << endl;
}

练习10.35

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>

using namespace std;
int main() {
	vector<int> ff = { 1,2,3,4,5,6,7,8,9 };
	vector<int>f;
	ostream_iterator<int> out(cout, "\n");
	for (auto it : ff)
		f.insert(f.begin(), it);
	copy(f.begin(), f.end(), out);
	cout << endl;
}

练习10.36

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>
#include <list>
using namespace std;
int main() {
	list<int> ff = { 1,2,3,4,5,6,7,8,9,1,2,3 };
	auto lasts = find(ff.rbegin(), ff.rend(),0);
	if (lasts == ff.rend())
		cout << "no value is equal 0";
	else
		cout << "have" << endl;
}

练习10.37

#include<fstream>
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
#include<algorithm>
#include <list>
using namespace std;
int main() {
	vector<int> ff = { 0,1,2,3,4,5,6,7,8,9 };
	list<int>f; int i = 0;
	for(auto it=ff.cbegin();it!=ff.cend() ;++it,++i)
	{
		if(i >= 3 && i < 7)
			f.push_back(*it);
	}
	ostream_iterator<int> out(cout, "\n");
	copy(f.begin(), f.end(), out);
	cout << endl;
}

10.5泛型算法结构

泛型算法所要求的迭代器一共5类

  • 输入迭代器:只读,不写,单遍扫描,只能递增
  • 输出迭代器:只写,不读,单遍扫描,只能递增
  • 前向迭代器:可读写,多遍扫描,只能递增
  • 双向迭代器:可读写,多遍扫描,可递增递减
  • 随机访问迭代器:可读写,多遍扫描,指出全部迭代器操作

10.6 特定容器算法

list和forward_list成员函数版本的算法

  • lst.merge(list2)
  • lst.merge(list2,comp)
  • lst.remove(val)
  • lst.remove_if(pred)
  • lst.reverse()
  • lst.sort()
  • lst.sort(comp)
  • lst.unique()
  • lst.unique(pred)

练习10.40

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<list>
#include<numeric>
using namespace std;
void elimdups(list<int>& vi) {
	vi.sort();
	vi.unique();
}
int main() {
	list<int>vi = { 1,2,3,23,23,12,12,23,32,3,423,3,2,21,2,3,4,67,8,9,6 };
	elimdups(vi);
	for (auto c : vi) {
		cout << c << endl;
	}
}

转载:https://blog.csdn.net/xhh22900/article/details/104503309
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场