您的位置:首页 > 编程语言 > C语言/C++

笔记:C++学习之旅---泛型算法

2016-09-23 01:22 459 查看
       标准库并未给每个容器定义成员函数来实现这些操作,而是定义了一组泛型算法(generic algorithm):称他们为”算法“,是因为他们实现了一些经典算法的公共接口,如排序和搜索:称他们是“泛型的”,是因为它们可以用于不同类型的元素和多种容器类型(不仅包括标准库类型,如vector或list,还包括内置的数组类型),以及我们将看到的,还能用于其他类型的序列。

练习10.3,10.4
#include
<iostream>
#include
<vector>
#include
<numeric>
using
namespace
std;
[align=left]
[/align]
int
main()
[align=left]{[/align]
            
vector<
int> vec;
            
int
i = 0;
            cout <<
"请输入整数"
<< endl;
            
while
(cin >> i)
[align=left]            {[/align]
                        
if
(i == -1)
                                    
break;
[align=left]                        vec.push_back(i);[/align]
[align=left]            }[/align]
            
int
val;
            cout <<
"请输入你要查找的数字\n"
;
[align=left]            cin >> val;[/align]
            
auto
result = find(vec.cbegin(), vec.cend(), val);
//查找输入的数字是否在容器中,在则显示the value x is present,否则显示the value is not present;
            cout <<
"The value "
<< val << (result == vec.cend() ?
" is not present\n "
:
" is present\n") << endl;//
            cout <<
"accumulate1:"
<< accumulate(vec.cbegin(), vec.cend(), 0)<<endl;//算出元素之和;
            
vector<
double> ivec = { 1.1, 2.2, 3.3, 4.4,5.5 };
            cout <<
"accumulate2:"
<< accumulate(ivec.cbegin(), ivec.cend(),
0.0)<<endl;  
//16.5   前面是double,一定要注意用0.0
            
return
0;
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]关键概念:算法永远不会执行容器的操作[/align]
[align=left][/align]
[align=left][/align]
[align=left]
[/align]
[align=left]
[/align]

慎用内联

内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?

如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?

内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的

执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收

获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,

消耗更多的内存空间。以下情况不宜使用内联:

(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。

(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。

类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构

函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数。

所以不要随便地将构造函数和析构函数的定义体放在类声明中。

一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明

了inline 不应该出现在函数的声明中)。

C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。

重排容器元素的算法(sort)、消除重复单词(unique)、使用容器操作删除元素(erase)
练习:10.9
实现你自己的elimDups。测试你的程序,分别在读取输入后,调用unique后以及调用erase后打印vector。
#include
<iostream>
#include
<vector>
#include
<string>
#include
<algorithm>
using
namespace
std;
[align=left]
[/align]
void
elimDups(vector
<string
> &vec
)
[align=left]{[/align]
            sort(
vec.begin(),
vec.end());
//排序
[align=left]
[/align]
            
auto
end_unique = unique(
vec.begin(),
vec.end());
//重排输入范围,使得每个单词只出现一次,找到重复元素;
            cout <<
"unique after\n";
[align=left]
[/align]
            
for
(
auto
i = 0; i !=
vec.size(); ++i)
[align=left]            {[/align]
                        cout<<
vec[i] <<
" ";
[align=left]            }[/align]
[align=left]            cout<< endl;[/align]
            
vec.erase(end_unique,
vec.end());
//删除重复元素
            cout <<
"erase after\n";
            
for
(
auto
i = 0; i !=
vec.size(); ++i)
[align=left]            {[/align]
                        cout <<
vec[i] <<
" ";
[align=left]            }[/align]
[align=left]            cout << endl;[/align]
[align=left]}[/align]
int
main()
[align=left]{[/align]
            
string
word;
            
vector<
string> vec;
            cout <<
"请输入一串单词(#结束)\n"
;
            
while
(cin >> word)
[align=left]            {[/align]
                        
if
(word ==
"#")
                                    
break;
[align=left]                        vec.push_back(word);[/align]
[align=left]            }[/align]
[align=left]            elimDups(vec);[/align]
[align=left]
[/align]
            
return
0;
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]lambda 表达式[/align]
[align=left][/align]
[align=left]
[/align]
[align=left]练习10.16[/align]
[align=left]使用lambda编写你自己版本的biggies.[/align]

#include
<iostream>
#include
<string>
#include
<vector>
#include
<algorithm>
using
namespace
std;
[align=left]
[/align]
void
elimpDups(vector<string> &s)
[align=left]{[/align]
            sort(s.begin(), s.end());
//排序;
            
auto
new_end = unique(s.begin(), s.end());
//找出重复元素;
            s.erase(new_end, s.end());
//删除重复元素;
[align=left]}[/align]
void
biggies(vector<string> &words, vector<string>::size_type sz,ostream &os = cout,char
c =
' '
)
[align=left]{[/align]
[align=left]            elimpDups(words);[/align]
            stable_sort(words.begin(), words.end(), [](string
const
&lhs, string
const
&rhs){
                        
return
lhs.size() < rhs.size();});
//按长度排序,长度相同的单词维持字典序;
                        
auto
wc = find_if(words.begin(), words.end(), [sz](string
const
&a){
                                    
return
a.size() >= sz;});
//找到满足size >= sz的元素数目;
                                    
/*for_each(wc, words.end(),[](const string &s){
[align=left]                                                cout << s << " ";});// 打印长度大于等于给定值的单词,每个单词后面接一个空格;[/align]
[align=left]                                                cout << endl;[/align]
[align=left]                                                */[/align]
                                    for_each(wc, words.end(), [&os, c](
const
string &s){
                                                os << s << c;});//加入引用捕获;ostream
&os = cout,char c = ' ';
[align=left]                                                os << endl;[/align]
[align=left]}[/align]
[align=left]void  fun1()[/align]
[align=left]{[/align]
[align=left]            size_t v1 = 42;[/align]
            
auto
f2 = [&v1]{
return
++v1; };
[align=left]            v1 = 0;[/align]
            
auto
j1 = f2();
            cout << j1 << endl;
//j1 = 1;
[align=left]}[/align]
void
fun2()
[align=left]{[/align]
[align=left]            size_t v1 = 42;[/align]
            
auto
f2 = [v1]()
mutable{
return
++v1; };
[align=left]            v1 = 0;[/align]
            
auto
j2 = f2();
            cout << j2 << endl;
//j2 = 43
[align=left]}[/align]
int
main()
[align=left]{[/align]
            vector<string> vec = {
"1234",
"1234"
,
"1234"
,
"hi~"
,
"alan"
,
"alan"
,
"cp"
,"a","abc"
};
[align=left]            biggies(vec,3);[/align]
            fun1();
//引用捕获
            fun2();
//变量捕获
            
return
0;

[align=left]}[/align]
[align=left][/align]
[align=left]默认情况下,对一个被拷贝的变量,lambda不会改变其值,如果我们希望能改变一个被捕获的变量的值,就必须在参数列表首加上关键字mutable。因此,可变的lambda能省略参数列表。[/align]
[align=left][/align]
[align=left][/align]
[align=left]引用捕获[/align]
[align=left][/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left][/align]
[align=left]
[/align]
[align=left]隐示捕获[/align]
[align=left][/align]
[align=left][/align]
[align=left]
[/align]
[align=left][/align]
[align=left]
[/align]
[align=left]谓词:是一个可调用的表达式,其返回结果是一个能用做条件的的值。标准库算法所使用的的谓词分为两类:一元谓词(意味着它只接受单一参数)、二元谓词(意味着它们有两个参数)。[/align]
[align=left][/align]
[align=left][/align]
[align=left]练习10.24:[/align]
[align=left]给定一个string,使用bind和chaeck_size在一个int的vector中查找第一个大于string长度的值。[/align]

#include
<iostream>
#include
<vector>
#include
<algorithm>
#include
<string>
#include
<functional>
using
namespace
std;
inline
bool
check_size(const
string
&s
,vector
<int
>::size_type
sz
)
[align=left]{[/align]
            
return
s.size() <
sz;
[align=left]}[/align]
inline
vector
<int
>::const_iterator
find_first_bigger(const
vector<int>
&vec,
const
string
&s
)
[align=left]{[/align]
            
return
find_if(
vec.cbegin(),
vec.cend(),
                        bind(check_size,
s, placeholders::_1));
[align=left]}[/align]
int
main()
[align=left]{[/align]
            
vector<
int> vec = { 1, 2, 3, 4, 5, 6 };
            
string
s = {
"test"
};
            cout << *find_first_bigger(vec, s)<<endl;
//5,找到第一个比字符串“test“ 4 大的数.
[align=left]
[/align]
            
return
0;

[align=left]}[/align]
[align=left]
[/align]
[align=left]再探迭代器[/align]
[align=left]除了为每个容器定义的迭代器之外,标准库在头文件iterator中还定义了额外几种迭代器:[/align]
[align=left]插入迭代器:这些迭代器被绑定到一个容器上,可以来向容器插入元素。[/align]
[align=left]流迭代器:这些迭代器被绑定到输入输出流上,可用来遍历所关联的IO流。[/align]
[align=left]反向迭代器:这些迭代器向后面不是向前移动,除了forword_list之外的标准库容器都有反向迭代器。[/align]
[align=left]移动迭代器:这些专用的迭代器不是拷贝其中的元素,而是移动它们。[/align]
[align=left]
[/align]
[align=left]插入迭代器[/align]
[align=left][/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]流迭代器[/align]
[align=left][/align]
[align=left][/align]
[align=left]
[/align]
[align=left]
[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: