C++ algorithm 中的部分方法的用法
一般情况下,algorithm 中的操作不是针对于对象本身而是迭代器
首先查看了algorithm 头文件 ps:(gcc)
#ifndef _GLIBCXX_ALGORITHM
#define _GLIBCXX_ALGORITHM 1
#pragma GCC system_header
#include <utility> // UK-300.
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithm>
#endif
#endif /* _GLIBCXX_ALGORITHM */
之后查看了bits/algorithmfwd.h
#ifndef _GLIBCXX_ALGORITHMFWD_H
#define _GLIBCXX_ALGORITHMFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_pair.h>
#include <bits/stl_iterator_base_types.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/*
adjacent_find
all_of (C++0x)
any_of (C++0x)
binary_search
copy
copy_backward
copy_if (C++0x)
copy_n (C++0x)
count
count_if
equal
equal_range
fill
fill_n
find
find_end
find_first_of
find_if
find_if_not (C++0x)
for_each
generate
generate_n
includes
inplace_merge
is_heap (C++0x)
is_heap_until (C++0x)
is_partitioned (C++0x)
is_sorted (C++0x)
is_sorted_until (C++0x)
iter_swap
lexicographical_compare
lower_bound
make_heap
max
max_element
merge
min
min_element
minmax (C++0x)
minmax_element (C++0x)
mismatch
next_permutation
none_of (C++0x)
nth_element
partial_sort
partial_sort_copy
partition
partition_copy (C++0x)
partition_point (C++0x)
pop_heap
prev_permutation
push_heap
random_shuffle
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
reverse
reverse_copy
rotate
rotate_copy
search
search_n
set_difference
set_intersection
set_symmetric_difference
set_union
shuffle (C++0x)
sort
sort_heap
stable_partition
stable_sort
swap
swap_ranges
transform
unique
unique_copy
upper_bound
......
上面这些应该是algoritm库中可以使用的函数,简单看了这个头文件里的部分函数之后以及用法,之后就开始了学习这部分知识的部分内容(伴随着C++primer)。
1、find()
在我们写程序的时候,经常会遇到查询某个元素是否在某一个块内,那么我们就可以使用find()这个方法,它的操作对象是迭代器。如果它查询的关键字或者是值存在这个块内,返回元素的迭代器,如果不存在返回尾部迭代器(cbegin())。
用法:
//这部分内容来自于bits/algorithmfwd.h
// find
template<typename _FIter1, typename _FIter2>
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
// find_first_of
// find_if
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_IIter
find_if_not(_IIter, _IIter, _Predicate);
#endif
.....
template<typename _IIter, typename _Tp>
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
//Binary predicate 二元谓词 用户自定义的或者标准库中的
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _IIter, typename _Predicate>
_IIter
find_if(_IIter, _IIter, _Predicate);
例子:
vector<string>fname{"google","alibaba","baidu","facebook","mi","ins"};
string filename;
if(find(fname.cbegin(),fname.cend(),"alibaba")!=fname.cend())
cout<<"alibaba 在这里!!"<<endl;
//现在迭代器指向的是谁?
cout<<"NOW :"<<*find(fname.cbegin(),fname.cend(),"alibaba")<<endl;
//输出: NOW :alibaba
2、find_first_of()
作用:查找一个对象迭代范围内,另一个对象迭代范围内的某一个元素。
我运用这个函数,发现他会先根据要查找的迭代范围内的元素[依次 依次 依次]进行判断是否在传来的迭代范围内。
例如:
vector<string>fname{"google","alibaba","baidu","facebook","mi","ins"};
list<string>fname1{"liubei","wangwei","nalanxingde","ins","alibaba"};
auto re=find_first_of(fname.cbegin(),fname.cend(),fname1.cbegin(),fname1.cend());
if(re!=fname.cend())
cout<<*re<<" 在这里!"<<endl;
无论我如何改变fname1中元素位置,它都会先从fname中选择一个元素进行查找,查找顺序google->alibaba->baidu->facebook->mi->ins.如果google 存在fname1中直接返回指向google的迭代器,如果没有查找alibaba,反复进行这几步,如果都没有返回尾部迭代器。
3、find_if()与find_if_not()
作用:
find_if(): 查找与给定谓词对其返回True的元素;
find_if_not(): 查找与给定谓词对其返回False的元素;
4、accumulate求和
这个函数它存在于numeric头文件中,其中我查看了bits/stl_numeric.h
template<typename _InputIterator, typename _Tp>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
_BinaryOperation __binary_op)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = __binary_op(__init, *__first);
return __init;
}
例如:
list<int> num{1,2,3,4,5,6,10,22,11,333};
//设置num初始和为0
cout<<"num 中元素的和为: "<<accumulate(num.cbegin(),num.cend(),0)<<endl;
//设置num初始和为100
cout<<"num 中元素的和为: "<<accumulate(num.cbegin(),num.cend(),100)<<endl;
/*输出: num 中元素的和为: 397
* num 中元素的和为: 497
*/
其中 accumulate 第三个参数 可以定义 这个“求和“运算规则和返回类型
例如:
cout<<"name:"<<accumulate(next(fname.cbegin()),fname.cend(),string(fname[0]),[](string a, string b) {return a + '-' + b;})<<endl;
//输出:name:google-alibaba-baidu-facebook-mi-ins
5、equal比较两个序列是否保存相同的值
用法: equal(A.cbegin(),A.cend(),B.cbegin());
由于接受一个单一的迭代器表示另一个序列,所以编译器假设第二个容器至少与第一个序列大长度相同,那么就意味着如果第二个如果小于第一个迭代器会把后面不属于第二个序列的元素也当作是第二个的。
例如:
vector<string>fname{"google","alibaba","baidu","facebook","mi","ins"};
vector<string>fname1{"liubei","wangwei","nalanxingde","ins","alibaba"};
auto fsize=fname.size();
fname1.resize(fsize);
auto be=equal(fname.cbegin(),fname.cend(),fname1.cbegin());
if(be)
cout<<"两个具有相同的。"<<endl;
else
cout<<"两个不同。"<<endl;
cout<<"fname size="<<fsize<<"\tfname1 size="<<fname1.size()<<endl;
/*输出:
两个不同。
fname size=6 fname1 size=6
*/
6、fill 相关操作
作用: 相容器内部填充值,如果填充的大小大于原容器大小,需要引入插入迭代器,因为算法不会对对象本身进行改变。
用法:
fill(iter_1,iter_2,value);
ADD:back_inserter 插入迭代器 需要引入 iterator 头文件
作用:向容器插入元素的迭代器。
用法:fill_n(back_inserter(fname),100,string(“bigboom”));
例如:
fill_n(back_inserter(fname),100,string("bigboom"));
cout<<"fname size="<<fname.size()<<endl;
cout<<"fname end="<<fname[105]<<endl;
//output : fname size= 106
//fname end=bigboom
如果改变vector容量的话,进行fill_n操作还是无效的;
7、copy 拷贝操作
作用:接受一个范围序列,把这个范围序列传递给第三个范围序列;
用法:copy(iter_1,iter_2,iter_3);
例如:
copy(fname1.cbegin(),fname1.cend(),ostream_iterator<string>(cout," "));
//output:liubei wangwei nalanxingde ins alibaba
8、replace和replace_copy操作
作用:
replace:四个参数,接受一个范围,在接受两个参数,一个为需要修改的值,一个是修改后的值;
replace_copy:五个参数,多一个迭代器,该迭代器的作用是,原来容器里的序列不会改变,而是将改变之后的序列copy到另一个容器当中;
用法:repalce(iter_1,iter_2,value_1,value_2);
repalce_copy(ietr_1,iter_2,back_inserter(vec),value_1,value_2);
例如:
copy(fname1.cbegin(),fname1.cend(),ostream_iterator<string>(cout," "));
cout<<endl;
replace(num.begin(),num.end(),1,100);
copy(num.cbegin(),num.cend(),ostream_iterator<int>(cout," "));
cout<<endl;
vector<int> vec;
replace_copy(num.begin(),num.end(),back_inserter(vec),100,101);
copy(num.cbegin(),num.cend(),ostream_iterator<int>(cout," "));
cout<<endl;
copy(vec.cbegin(),vec.cend(),ostream_iterator<int>(cout," "));
cout<<endl;