cppPrimer学习-10th
cppPrimer学习10th
目录
备忘
- 只读算法
find
count
accumulate //求和
equal
- 写容器算法
fill
fill_n fill_n(v.begin(), v.size(), 0);
// back_inserter(containter) 返回一个插入的迭代器,对他赋值执行push_back
copy
sort
unique
stable_sort
-
谓词 P344
-
equal 比较的是
==
,对于char*
的类型实际比较的是char*
也就是地址,而对于string来说,有重载==
操作符 -
unique
删除重复之前需要排序,它只是删除相邻相同的元素 -
迭代器类别
输入迭代器:只读,不写;单遍扫描,只能递增。支持==、!=、++、*、-> 输出迭代器:只写,不读;单遍扫描,只能递增。支持++、* 前向迭代器:可读写,多边扫描,只能递增。支持输入输出迭代器的所有操作。 双向迭代器:可读写,多遍扫描,可递增递减。除支持前向迭代器的操作外,还支持--。 随机访问迭代器:可读写,多遍扫描,支持全部迭代器运算。除支持双向操作外,还支持<、<=、>、>=、+、+=、-、-=、迭代器的减法运算符(-)、下标运算符(iter[n], *(iter[n]) )。
-
对于
list
和forward_list
,应该使用容器定义的成员函数的算法,因为一方面链表可以直接修改链接达到交换元素的目的,另一方面比如sort需要支持随机访问而链表不支持等 p369
10.1
/*
头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数。count返回给定值在序列中出现的次数。
编写程序,读取int序列存入vector中,打印有多少个元素的值等于给定值
*/
#include "algorithm"
#include "include.h"
int main(int argc, char const *argv[])
{
vector<int> v = {1, 2, 3, 4, 5, 6, 3, 8, 9, 3, 5, 5};
auto findme = count(v.begin(), v.end(), 3);
cout << findme << endl;
while (1)
;
return 0;
}
10.2
/*
头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数。count返回给定值在序列中出现的次数。
编写程序,读取string序列存入list中,打印有多少个元素的值等于给定值
*/
#include "include.h"
int main(int argc, char const *argv[])
{
list<string> l = {"123", "456", "111", "123", "456", "123"};
auto has = count(l.begin(), l.end(), "123");
cout << "123 has " << has << endl;
while (1)
;
return 0;
}
10.3
10.4
/*用accumulate求一个vector中的元素之和*/
/*假定v是一个vector, 那么调用accumulate(v.cbegin(), v.cend(), 0)有何错误(如果存在)
返回的是int
*/
#include "include.h"
int main(int argc, char const *argv[])
{
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
auto sum = accumulate(v.begin(), v.end(), 0);
cout << sum << endl;
vector<double> v2 = {1.1, 1.2};
auto sum2 = accumulate(v2.begin(), v2.end(), (double)0); //或者0.0都可以
cout << sum2 << endl;
while (1)
;
return 0;
}
10.5
/*
在本节对名册(roster)调用equal的例子中,如果两个名册中保存的都是c风格字符串而不是string,会发生什么?
答案: 比较的是迭代器指的地址在使用char* 的类型
equal使用==运算符比较两个序列中的元素。string类重载了==,可比较两个字符串是否长度相等且其中元素对位相等。
而C风格字符串本质是char *类型,用==比较两个char *对象,只是检查两个指针值是否相等,即地址是否相等,而不会比较其中字符是否相同。
所以,只有当两个序列中的指针都指向相同的地址时,equal才会返回true,否则,即使字符串内容完全相同,也会返回false。
原文链接:https://blog.csdn.net/sunhero2010/article/details/49803965
For such case, std::equal is going to compare the address value rather than the string value.
So the result is not the same as std::string. Try to avoid coding this way.
*/
#include "include.h"
void printAddr(const char *addr)
{
unsigned int a;
for (int i = 0; i < 6; i++)
{
a = (*(addr + i)) & 0xff;
cout << a << " ";
}
cout << endl;
}
int main(int argc, char const *argv[])
{
// const char *s1 = "123456789";
// const char *s2 = "123456789111111";
// auto ret = equal(begin(s1), end(s1), begin(s2));
// cout << ret << endl;
std::vector<const char *> roster1{"Mooophy", "pezy", "Queequeg"};
std::list<const char *> roster2{"Mooophy", "pezy", "Queequeg", "shbling", "evan617"};
std::cout << boolalpha << std::equal(roster1.cbegin(), roster1.cend(), roster2.cbegin()) << endl;
const char a[3][2] = {"A", "B", "C"};
const char b[3][2] = {"A", "B", "C"};
std::vector<const char *> v1(std::begin(a), std::end(a));
std::list<const char *> v2(std::begin(b), std::end(b));
cout << "a=" << begin(a) << "----" << end(a) << endl;
printAddr((const char *)&(*begin(a)));
cout << "b=" << begin(b) << "----" << end(b) << endl;
printAddr((const char *)&(*begin(b)));
std::cout << std::boolalpha
<< std::equal(v1.cbegin(), v1.cend(), v2.cbegin()) << std::endl;
cout << "v1_address=" << &*v1.begin() << "----" << &*v1.end() << endl;
cout << "v2_address=" << &*v2.begin() << "----" << &*v2.end() << endl;
printAddr((const char *)&(*v1.begin()));
printAddr((const char *)&(*v2.begin()));
vector<string> v3{"A", "B", "C"};
vector<string> v4{"A", "B", "C"};
cout << "v3_address=" << &*v3.begin() << "----" << &*v3.end() << endl;
cout << "v4_address=" << &*v4.begin() << "----" << &*v4.end() << endl;
printAddr((const char *)&(*v3.begin()));
printAddr((const char *)&(*v4.begin()));
std::cout << std::boolalpha
<< std::equal(v3.cbegin(), v3.cend(), v4.cbegin()) << std::endl;
while (1)
;
return 0;
}
10.6
/*
编写程序,使用fill_n将一个序列中的int都设置为0
*/
#include "include.h"
int main(int argc, char const *argv[])
{
vector<int> v = {1, 2, 3, 4, 5, 6, 7};
fill_n(v.begin(), v.size(), 0);
print(v);
while (1)
;
return 0;
}
10.7
/*
下面程序是否有错误?如果有,请改正。
reserve 只是确保当前size<capacity,扩充容量但是不会改变size
*/
#include "include.h"
int main(int argc, char const *argv[])
{
vector<int> vec;
list<int> lst;
int i;
while (cin >> i)
lst.push_back(i);
//-------------------
vec.reserve(lst.size()); // 虽然不会报错误,但是不会有打印的
//vec.resize(lst.size());
copy(lst.cbegin(), lst.cend(), vec.begin());
print(vec);
while (1)
;
return 0;
}
10.8
标准库算法不会改变他们所操作的容器的大小。为什么使用back_inserter不会使这一断言失效
标准库算法根本不知道有“容器”这个东西。它们只接受迭代器参数,运行于这些迭代器之上,通过这些迭代器来访问元素。
back_inserter 的迭代器能调用对应的插入算法
10.9
/*
实现你自己的elimDups。测试你的程序,分别在读取输入后、调用unique后以及调用erase后打印vector的内容
*/
#include "include.h"
void elimDups(vector<string> &s)
{
print(s);
sort(s.begin(), s.end());
print(s);
auto last = unique(s.begin(), s.end());
print(s);
s.erase(last, s.end());
print(s);
}
int main(int argc, char const *argv[])
{
vector<string> vs = {"999",
"123",
"456",
"123",
"777",
"999"};
elimDups(vs);
while (1)
;
return 0;
}
10.10
你认为算法不改变容器大小的原因是什么?
泛型算法为了实现通用化,识别的是迭代器,改变容器大小会使迭代器失效,泛型算法原则上也不知道容器的存在
10.11
/*
编写程序,使用 stable_sort 和isShorter将传递给你的elimDups版本的vector排序。打印vector的内容,验证你的程序的正确性。
*/
#include "include.h"
bool isShorter(const string &a, const string &b)
{
return a.size() < b.size();
}
void elimDups(vector<string> &s)
{
print(s);
sort(s.begin(), s.end());
print(s);
auto last = unique(s.begin(), s.end());
print(s);
s.erase(last, s.end());
print(s);
stable_sort(s.begin(), s.end(), isShorter);
print(s);
}
int main(int argc, char const *argv[])
{
vector<string> vs = {"9990000",
"123000000000",
"456",
"123000000000",
"777",
"9990000"};
elimDups(vs);
while (1)
;
return 0;
}
10.12
//编写名为compareIsbn的函数,比较两个Sales_data对象的isbn()成员。使用这个函数排序一个保存Sales_data对象的vector。
#include "Sales_data.h"
#include "include.h"
bool compareIsbn(const Sales_data &a, const Sales_data &b)
{
return a.isbn() < b.isbn();
}
int main(int argc, char const *argv[])
{
Sales_data a("999");
Sales_data b("456");
Sales_data c("222");
vector<Sales_data> v = {a, b, c};
sort(v.begin(), v.end(), compareIsbn);
for (auto ch : v)
{
cout << ch.isbn() << endl;
}
while (1)
;
return 0;
}
10.13
/*
标准库定义了名为partition的算法,它接受一个谓词,对容器内容进行划分,使得谓词为true的值对排在容器的前半部分,而使谓词为false的值会排在后半部分。
算法返回一个迭代器,指向最后一个使谓词为true的元素之后的位置。编写函数,接受一个string,返回一个bool值,指出string是否有5个或更多字符。
使用此函数划分words。打印出长度大于等于5的元素
*/
#include "include.h"
bool bigThen5(const string &a)
{
return a.size() > 5;
}
int main(int argc, char const *argv[])
{
vector<string> v = {"123456",
"12345",
"111222",
"55555555"};
auto last_true = partition(v.begin(), v.end(), bigThen5);
for (auto i = v.begin(); i != last_true; i++)
{
cout << *i << endl;
}
while (1)
;
return 0;
}
10.14
/*
lamdda 接收两个int 返回sum
*/
#include "include.h"
int main(int argc, char const *argv[])
{
auto f = [](const int a, const int b) { return a + b; };
cout << f(1, 2) << endl;
while (1)
;
return 0;
}
10.15
/*
编写一个lambda,捕获它所在函数的int,并接受一个int参数。lambda应该返回捕获的int和int参数的和
*/
#include "include.h"
int main(int argc, char const *argv[])
{
int a = 1;
auto f = [a](int b) { return a + b; };
cout << f(3) << endl;
while (1)
;
return 0;
}
10.16
/*
求一个大于等于给定长度的单词有多少,并将其打印出来
void biggiest(vector<string>v,vector<string>::size_type sz)
*/
#include "include.h"
void biggiest(vector<string> v, vector<string>::size_type sz)
{
// 按照字典排序,删除重复单词
sort(v.begin(), v.end());
auto last = unique(v.begin(), v.end());
v.erase(last, v.end());
// 按照长度排序,这里需要传递一个长度 使用lamada
stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
//找到第一个长度>sz的迭代器
auto fst = find_if(v.begin(), v.end(), [sz](const string &a) { return a.size() >= sz; });
// 打印vec
for_each(fst, v.end(), [](const string &a) { cout << a << endl; });
}
int main(int argc, char const *argv[])
{
vector<string> v = {"0", "123", "1234", "hello", "world", "99999999999", "world"};
biggiest(v, 4);
while (1)
;
return 0;
}
10.17
//重新10.12的程序,在对sort的调用中使用lambda来代替函数compareIsbn
#include "Sales_data.h"
#include "include.h"
bool compareIsbn(const Sales_data &a, const Sales_data &b)
{
return a.isbn() < b.isbn();
}
int main(int argc, char const *argv[])
{
Sales_data a("999");
Sales_data b("456");
Sales_data c("222");
vector<Sales_data> v = {a, b, c};
vector<Sales_data> v2(v);
sort(v.begin(), v.end(), compareIsbn);
for (auto ch : v)
{
cout << ch.isbn() << endl;
}
sort(v2.begin(), v2.end(), [](const Sales_data &a, const Sales_data &b) { return a.isbn() < b.isbn(); });
for (auto ch : v2)
{
cout << ch.isbn() << endl;
}
while (1)
;
return 0;
}
10.18
10.19
/*
求一个大于等于给定长度的单词有多少,并将其打印出来
void biggiest(vector<string>v,vector<string>::size_type sz)
-------------------------------sort by dic
0,123,1234,99999999999,hello,world,
-------------------------------sort by dic,then stable_sort by len,then use findif
1234,hello,world,99999999999,
-------------------------------sort by dic,then partition
world,hello,1234,99999999999,
-------------------------------sort by dic,then stable_partition
1234,99999999999,hello,world,
*/
#include "include.h"
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1) ? word + ending : word;
}
void elimdups(vector<string> &words)
{
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
}
void biggiest2(vector<string> &words, vector<string>::size_type sz)
{
elimdups(words); //将words按字典序排序,删除重复词
// 获取一个迭代器,指向最后一个满足size()>=sz的元素之后的位置
auto wc = partition(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });
// 计算满足size()>=sz的元素的数目
auto count = wc - words.begin();
cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
// 打印长度大于等于给定值的单词,每个单词后面接一个空格
for_each(words.begin(), wc, [](const string &s) { cout << s << " "; });
cout << endl;
}
void biggiest(vector<string> v, vector<string>::size_type sz)
{
// 按照字典排序,删除重复单词
sort(v.begin(), v.end());
auto last = unique(v.begin(), v.end());
v.erase(last, v.end());
vector<string> cp1(v);
vector<string> cp2(v);
cout << "-------------------------------sort by dic" << endl;
for_each(cp1.begin(), cp1.end(), [](const string &a) { cout << a << ","; });
cout << endl;
cout << "-------------------------------sort by dic,then stable_sort by len,then use findif" << endl;
// 按照长度排序,这里需要传递一个长度 使用lamada
stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
//找到第一个长度>sz的迭代器
auto fst = find_if(v.begin(), v.end(), [sz](const string &a) { return a.size() >= sz; });
// 打印vec
for_each(fst, v.end(), [](const string &a) { cout << a << ","; });
cout << endl;
cout << "-------------------------------sort by dic,then partition" << endl;
auto lst = partition(cp1.begin(), cp1.end(), [sz](const string &a) { return a.size() >= sz; });
for_each(cp1.begin(), lst, [](const string &a) { cout << a << ","; });
cout << endl;
cout << "-------------------------------sort by dic,then stable_partition" << endl;
auto lst2 = stable_partition(cp2.begin(), cp2.end(), [sz](const string &a) { return a.size() >= sz; });
for_each(cp2.begin(), lst2, [](const string &a) { cout << a << ","; });
cout << endl;
}
int main(int argc, char const *argv[])
{
vector<string> v = {"0", "123", "1234", "hello", "world", "99999999999", "world"};
biggiest(v, 4);
while (1)
;
return 0;
}
10.20
/*
标准库定义了一个名为count_if的算法。类似find_if,此函数接受一对迭代器,表示一个输入范围,还接受一个谓词,会对输入范围中每个元素执行。
count_if返回一个计数值,表示谓词有多少次为真。使用count_if重写我们程序中统计有多少单词长度超过6的部分。
*/
#include "include.h"
int main(int argc, char const *argv[])
{
vector<string> v = {"123", "1233", "ssss", "123456789", "123564789"};
auto cnt = count_if(v.begin(), v.end(), [](const string &a) { return a.size() > 6; });
cout << cnt << endl;
while (1)
;
return 0;
}
10.21
/*
编写一个lambda,捕获一个局部int变量,并递减变量值,直至它变为0.一旦变为0,再调用lambda应该不再递减变量。lambda应该返回一个bool值,指出捕获的变量是否为0.
*/
#include "include.h"
int main(int argc, char const *argv[])
{
int z = 3;
//auto f = [&z]() {if(z)z--; return(z?false:true); };
// 也可以使用尾置返回
auto f = [&z]() -> int {if(z)z--; return(z?false:true); };
while (z)
{
f();
cout << z << endl;
}
while (1)
;
return 0;
}
10.22
/*
重写统计长度小于等于6的单词数量的程序,使用函数代替lambda.
*/
#include "include.h"
#include <functional>
using namespace std::placeholders;
bool cnt(const string &a, string::size_type sz)
{
return a.size() <= sz;
}
int main(int argc, char const *argv[])
{
vector<string> v = {"123", "1233", "ssss", "123456789", "123564789"};
//auto f = bind(cnt, _1, 6);
//auto cnt = count_if(v.begin(), v.end(), f);
auto cnt = count_if(v.begin(), v.end(), bind(cnt, _1, 6));
cout << cnt << endl;
while (1)
;
return 0;
while (1)
;
return 0;
}
10.23
bind接受几个参数
第一个参数是函数,后面的参数实际就是函数的参数,
10.24
#include "include.h"
bool check(int a, int sz)
{
return a > sz;
}
int main(int argc, char const *argv[])
{
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
string s = "123";
auto f = bind(check, _1, s.size());
auto fst = find_if(v.begin(), v.end(), f);
cout << *fst << endl;
while (1)
;
return 0;
}
10.25
/*
求一个大于等于给定长度的单词有多少,并将其打印出来
void biggiest(vector<string>v,vector<string>::size_type sz)
在10.3.2节的练习中,编写了一个使用 partition 的biggies版本.使用check_size和bind重写此函数
//----------这里是本章答案
auto f1 = bind(check, _1, sz);
cout << "-------------------------------sort by dic,then bind" << endl;
auto lstbind = partition(cp3.begin(), cp3.end(), f1);
for_each(cp3.begin(), lstbind, [](const string &a) { cout << a << ","; });
cout << endl;
-------------------------------sort by dic
0,123,1234,99999999999,hello,world,
-------------------------------sort by dic,then stable_sort by len,then use findif
1234,hello,world,99999999999,
-------------------------------sort by dic,then partition
world,hello,1234,99999999999,
-------------------------------sort by dic,then stable_partition
1234,99999999999,hello,world,
*/
#include "include.h"
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1) ? word + ending : word;
}
void elimdups(vector<string> &words)
{
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
}
void biggiest2(vector<string> &words, vector<string>::size_type sz)
{
elimdups(words); //将words按字典序排序,删除重复词
// 获取一个迭代器,指向最后一个满足size()>=sz的元素之后的位置
auto wc = partition(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });
// 计算满足size()>=sz的元素的数目
auto count = wc - words.begin();
cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
// 打印长度大于等于给定值的单词,每个单词后面接一个空格
for_each(words.begin(), wc, [](const string &s) { cout << s << " "; });
cout << endl;
}
bool check(const string &a, string::size_type sz)
{
return a.size() >= sz;
}
void biggiest(vector<string> v, vector<string>::size_type sz)
{
// 按照字典排序,删除重复单词
sort(v.begin(), v.end());
auto last = unique(v.begin(), v.end());
v.erase(last, v.end());
vector<string> cp1(v);
vector<string> cp2(v);
vector<string> cp3(v);
cout << "-------------------------------sort by dic" << endl;
for_each(cp1.begin(), cp1.end(), [](const string &a) { cout << a << ","; });
cout << endl;
cout << "-------------------------------sort by dic,then stable_sort by len,then use findif" << endl;
// 按照长度排序,这里需要传递一个长度 使用lamada
stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
//找到第一个长度>sz的迭代器
auto fst = find_if(v.begin(), v.end(), [sz](const string &a) { return a.size() >= sz; });
// 打印vec
for_each(fst, v.end(), [](const string &a) { cout << a << ","; });
cout << endl;
//------------------------------------------------------------------------------------------------------------这里是本章答案
auto f1 = bind(check, _1, sz);
cout << "-------------------------------sort by dic,then bind" << endl;
auto lstbind = partition(cp3.begin(), cp3.end(), f1);
for_each(cp3.begin(), lstbind, [](const string &a) { cout << a << ","; });
cout << endl;
cout << "-------------------------------sort by dic,then partition" << endl;
auto lst = partition(cp1.begin(), cp1.end(), [sz](const string &a) { return a.size() >= sz; });
for_each(cp1.begin(), lst, [](const string &a) { cout << a << ","; });
cout << endl;
cout << "-------------------------------sort by dic,then stable_partition" << endl;
auto lst2 = stable_partition(cp2.begin(), cp2.end(), [sz](const string &a) { return a.size() >= sz; });
for_each(cp2.begin(), lst2, [](const string &a) { cout << a << ","; });
cout << endl;
}
int main(int argc, char const *argv[])
{
vector<string> v = {"0", "123", "1234", "hello", "world", "99999999999", "world"};
biggiest(v, 4);
while (1)
;
return 0;
}
10.26
解释三种插入迭代器的不同之处
back_inserter 总是执行push_back 尾部插入
front_inserter 执行 push_front 头部插入
inserter(container,where) 在where前插入后,返回where 也就是原来的迭代器的位置
10.27
/*
除了unique之外,标准库还定义了名为unique_copy的函数,
它接受第三个迭代器,表示拷贝不重复元素的目的位置。
编写一个程序,使用unique_copy将一个vector中不重复的元素拷贝到一个初始为空的list中
*/
#include "include.h"
int main(int argc, char const *argv[])
{
vector<int> v = {1, 2, 3, 4, 5, 2, 3, 1, 4, 1, 2, 3, 4, 5, 9};
list<int> l;
sort(v.begin(), v.end());
auto last = unique_copy(v.begin(), v.end(), back_inserter(l));
for_each(l.begin(), l.end(), [](const int &i) { cout << i << " "; });
cout << endl;
while (1)
;
return 0;
}
10.28
/*
一个vector中保存1到9共9个值,将其拷贝到三个其他容器中。分别使用inserter、back_inserter 和front_inserter将元素添加到三个容器中。
对每种 inserter,估计输出序列是怎样的,运行程序验证你的估计是否正确
*/
#include "include.h"
int main(int argc, char const *argv[])
{
vector<int> v;
list<int> v1;
list<int> v2;
list<int> v3;
for (int i = 0; i < 9; i++)
v.push_back(i);
copy(v.begin(), v.end(), inserter(v1, v1.begin())); // 0,1,2,3,4,5,6,7,8,
copy(v.begin(), v.end(), back_inserter(v2)); // 0,1,2,3,4,5,6,7,8,
copy(v.begin(), v.end(), front_inserter(v3)); // 8,7,6,5,4,3,2,1,0,
for_each(v1.begin(), v1.end(), [](const int ch) { cout << ch << ","; });
cout << endl;
for_each(v2.begin(), v2.end(), [](const int ch) { cout << ch << ","; });
cout << endl;
for_each(v3.begin(), v3.end(), [](const int ch) { cout << ch << ","; });
cout << endl;
while (1)
;
return 0;
}
10.29
/*
编写程序,使用流迭代器读取一个文本文件,存入一个vector中的string里
1: vector<string> v(in_iter, eof_f);
2: copy(in_iter, eof_f, back_inserter(vec));
*/
#include <fstream>
#include <iterator>
#include "include.h"
int main(int argc, char const *argv[])
{
ifstream in_f("E:\\Reading\\C++\\C+++Primer\\CppPrimer-master\\CppPrimer\\10th\\10.29.cpp");
istream_iterator<string> in_iter(in_f);
istream_iterator<string> eof_f;
// 方式1
vector<string> v(in_iter, eof_f);
for_each(v.begin(), v.end(), [](const string &ch) { cout << ch << endl; });
//方式2
vector<string> vec;
copy(in_iter, eof_f, back_inserter(vec));
std::copy(v.cbegin(), v.cend(), std::ostream_iterator<string>(std::cout, "\n"));
while (1)
;
return 0;
}
10.30
/*使用流迭代器、sort和copy从标准输入读取一个整数序列,将其排序,并将结果写到标准输出
*/
#include "include.h"
#include <iterator>
int main(int argc, char const *argv[])
{
istream_iterator<int> in(cin), eof;
ostream_iterator<int> out(cout, ",");
vector<int> v(in, eof);
sort(v.begin(), v.end());
copy(v.begin(), v.end(), out);
while (1)
;
return 0;
}
10.31
/*
修改前一题的程序,使其只打印不重复的元素。你的程序应使用unique_copy
*/
#include "include.h"
#include <iterator>
int main(int argc, char const *argv[])
{
istream_iterator<int> in(cin), eof;
ostream_iterator<int> out(cout, ",");
vector<int> v(in, eof);
sort(v.begin(), v.end());
//_copy(v.begin(), v.end(), out);
unique_copy(v.begin(), v.end(), out);
while (1)
;
return 0;
}
10.32
/*
10.32 重写1.6节的书店程序,使用一个vector保存交易记录,使用不同算法完成处理。使用sort和10.3.1节中的compareIsbn函数来排序交易记录,然后使用find和accumulate求和。
*/
#include "include.h"
#include "../include/Sales_item.h"
#include <numeric>
#include <iterator>
void TestNew()
{
cout << "Usage input: name_id[string] ,count[unsigned] , value[doubel]" << endl;
istream_iterator<Sales_item> in(cin), eof;
vector<Sales_item> v(in, eof);
sort(v.begin(), v.end(), compareIsbn);
for (auto beg = v.cbegin(), end = beg; beg != v.cend(); beg = end)
{
end = find_if(beg, v.cend(), [beg](const Sales_item &nextv) { return nextv.isbn() != beg->isbn(); });
cout << accumulate(beg, end, Sales_item(beg->isbn())) << endl;
}
// std::istream_iterator<Sales_item> in_iter(std::cin), in_eof;
// std::vector<Sales_item> vec;
// while (in_iter != in_eof)
// vec.push_back(*in_iter++);
// sort(vec.begin(), vec.end(), compareIsbn);
// for (auto beg = vec.cbegin(), end = beg; beg != vec.cend(); beg = end)
// {
// end = find_if(beg, vec.cend(), [beg](const Sales_item &item) { return item.isbn() != beg->isbn(); });
// std::cout << std::accumulate(beg, end, Sales_item(beg->isbn())) << std::endl;
// }
}
int TestOld(void)
{
cout << "Usage input: name_id[string] ,count[unsigned] , value[doubel]" << endl;
Sales_item last;
if (cin >> last)
{
Sales_item now;
while (cin >> now)
{
if (now.isbn() == last.isbn())
{
last += now;
}
else
{
cout << last << endl;
last = now;
}
}
cout << now << endl;
}
else
{
cout << "input err " << endl;
return -1;
}
return 0;
}
int main(int argc, char const *argv[])
{
//TestOld();
TestNew();
while (1)
;
return 0;
}
10.33
/*
编写程序,接受三个参数:一个输入文件和两个输出文件的文件名。输入文件保存的应该是整数。
使用istream_iterator读取输入文件。使用ostream_iterator将奇数写入第一个输出文件,每个值之后都跟一个空格。
将偶数写入第二个输出文件,每个值都独占一行
*/
#include "include.h"
#include <fstream>
#include <iterator>
int main(int argc, char const *argv[])
{
const char *path = "D:\\0.txt";
const char *path1 = "D:\\1.txt";
const char *path2 = "D:\\2.txt";
ifstream fin(path);
ofstream fout1(path1);
ofstream fout2(path2);
if (!fin)
cout << "open" << path << "faile" << endl;
if (!fout1)
cout << "open" << path1 << "faile" << endl;
if (!fout2)
cout << "open" << path2 << "faile" << endl;
if (!fin || !fin || !fout2)
while (1)
;
istream_iterator<int> in(fin), iof;
ostream_iterator<int> o1(fout1, " ");
ostream_iterator<int> o2(fout2, "\n");
while (in != iof)
{
cout << *in << endl;
if (*in & 0x01)
{
*o1++ = *in;
}
else
{
*o2++ = *in;
}
in++;
}
fout1.close();
fout2.close();
while (1)
;
return 0;
}
10.34
10.35
/*
1. 反向迭代器 逆序输出vector
2. 普通迭代器 逆序输出
*/
#include "include.h"
#include <iterator>
int main(int argc, char const *argv[])
{
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
copy(v.crbegin(), v.crend(), ostream_iterator<int>(cout, ","));
cout << endl;
//copy(v.crbegin(), v.crend(), ostream_iterator<int>(cout, ","));
auto beg1 = v.end() - 1;
for (; beg1 != v.begin(); advance(beg1, -1))
{
cout << *beg1 << ",";
}
cout << *beg1 << endl;
while (1)
;
return 0;
}
10.36
10.37
/*使用find在一个int的list中查找最后一个值为0的元素。*/
/*给定一个包含10个元素的vector,将位置3到7之间的元素按逆序拷贝到一个list中*/
#include "include.h"
int main(int argc, char const *argv[])
{
list<int> l = {1, 2, 3, 5, 0, 1, 2, 5, 8, 2, 0, 3, 15};
auto last_zero_it = find(l.crbegin(), l.crend(), 0);
cout << distance(last_zero_it, l.crend()) << endl;
for_each(l.cbegin(), last_zero_it.base(), [](const int c) { cout << c << ","; });
cout << endl;
//////////end -1 -2
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
list<int> l2(v.rend() - 7, v.rend() - 2);
for_each(l2.cbegin(), l2.cend(), [](const int c) { cout << c << ","; });
//// 另一种方式,但是他这种对于vector不友好,一直在头部插入,对于list无所谓
////copy(vec.cbegin() + 3, vec.cbegin() + 8, ret_lst.rbegin());
while (1)
;
return 0;
}
10.38
5个迭代器的类别:
迭代器 | 简述 | |
---|---|---|
输入 | 只读 | 解引用在=右侧,用一次,迭代器支持!=,==,++,-> |
输出 | 只写 | 解引用在=左侧,用一次,迭代器支持++ |
前向 | 只能递增 | 可以多次读写同一个位置 |
双向 | 能加能减 | |
随机 | +-具体数字 | 可以使用下标 |
10.39
10.40
list 双向迭代
vec 随机迭代器
cop 输入迭代器,输出迭代器
reverse 需要将范围内的元素反向处理,>>>双向迭代器
unique 去除相邻的重复元素,也就是逐一扫描->>>前向
10.41
/*仅根据算法和参数的名字,描述下面每个标准库算法执行什么操作*/
replace(beg, end, old_val, new_val); 1.替换范围内的old_val元素为 new_val
replace_if(beg, end, pred, new_val); 2.元素满足pred的条件,替换为new_val
replace_copy(beg, end, dest, old_val, new_val); 3. 使用copy而非直接替换
replace_copy_if(beg, end, dest, pred, new_val); 4. 使用copy而非直接替换
10.42
/*
使用list代替vector重新实现10.2.3节中的去除重复单词的程序
*/
#include "include.h"
int main(int argc, char const *argv[])
{
list<string> l = {"1",
"my",
"2",
"3",
"2",
"heel",
"my"};
l.sort();
l.unique();
for_each(l.begin(), l.end(), [](const string &c) { cout << c << endl; });
while (1)
;
return 0;
}