C++之算法和映射

算法和映射

标准库算法

标准库大约提供了80种有用的算法。

挑选的标准算法

r = find(b,e,v)     r值想[b:e]中v首次出现的位置
r = find_if(b,e,p)  r指向[b:e]中令p(x)为true的第一个元素x
x = count(b,e,v)    x为v在[b:e]中出现的次数
x = count_if(b,e,p)  x为[b:e]中满足p(x)为true的元素的个数
sort(b,e)           用<运算符对[b:e]排序
sort(b,e,p)         用谓词p对[b:e]排序
copy(b,e,b2)        将[b:e]拷贝至[b2:b2+(e-b)]; b2之后应用足够的空间用哦关于存储元素
unique_copy(b,e,b2) 将[b:e]拷贝至[b2:b2+(e-b)]; 不拷贝相邻的重复元素
merge(b,e,b2,e2,r)  将有序序列[b2:e2]和[b:e]合并,并放入[r:r+(e-b)+(e2-b2)]之中
r = equal_range(b,e,v) r是有序范围[b:e]的一个子序列,且其中所有元素值均为v,本质上是通过二分搜索查找v
equal(b,e,b2)       [b:e]和[b2:b2+(e-b)]的所有元素对应相等?
x = accumulate(b,e,i) x是将i与[b:e]中所有元素进行累加的结果
x = accumulate(b,e,i,op) 与accumulate类似,但用op进行求和运算
x = inner_product(b,e,b2,i) x是[b:e]与[b2:b2+(e-b)]的内积
x = inner_product(b,e,b2,i,op,op2) 与inner_product类似,但用op和op2取代内积的+和*


最简单的算法 find()
template<typename In, typename T>

In find(In first, In last, const T& val)
{
    while (first!=last&&*first!=val) ++first;
    return first;
}

void f(vector<int>& v, int x)
{
    auto p = find(v.begin(), v.end(), x);
    if (p!=v.end())
    {
        //我们在v中找到了x
    }
    else
    {
        //v中没有x
    }
}

auto ch = 'c'; //ch是一个char
auto d = 2.1; //d是一个double


lambda表达式


数值算法

在STL标准库中只有四种数值算法:
x = accumulate(b,e,i) 
 累加序列中的值,例如,对{a,b,c,d}计算{i+a+b+c+d}。
结果x的类型与初始值i的类型一致。

x = inner_product(b,e,b2,i)  
将两个序列的对应元素相乘并将结果累加。例如,对{a,b,c,d}和{e,f,g,h}计算i+a*e+b*f+c*g+d*h。
结果x的类型与初始值i的类型一致。

r = partial_sum(b,e,r)
对一个序列的前n个元素进行累加,并将累加结果生成一个序列。例如,
对{a,b,c,d}将生成{a,a+b,a+b+c,a+b+c+d}

r = adjacent_diffenrence(b,e,b2,r)
对一个序列的相邻元素进行减操作,并将得到的差生成一个序列。
例如,对{a,b,c,d}将生成{a, b-a, c-b, d-c}


关联容器


一个map就是一个(键,值)对的有序序列,你可以基于一个关键字在其中查找对应的值,
流行的和有用的概念似乎总是由很多名称。在标准库中,我们将这类数据结构统称为关联容器(associative container).

标准库提供了8个关联容器:
map          (键,值)对的有序容器
set           关键字的有序容器
unordered_map (键,值)对的无序容器
unordered_set  关键字的无序容器
multimap       关键字可以出现多次的map
multiset       关键字可以出现多次的set
unordered_multimap 关键字可以出现多次的unoedered_map
unordered_multiset 关键字可以出现多次的unoedered_set  


map


int main()
{
    map<string,int> words; //维护(单词,频率)对

    for (string s; cin>>s; )
        ++words[s];  //注意:用string作为words的下标

    for (const auto& p:words)
        count<<p.first<<":"p.second<<'\n';
}


words["sultan"]

for(string s; cin>>s;)
    ++words[s];      // 注意:用string作为words的下标

一个map<string, int>的元素是pair<string,int>。 每个pair的第一个元素名为first,第二个元素名为
second,因此输出循环为
for (const auto& p : words)
    count << p.first << ":" p.second << '\n';


map概览

映射的实现有很多种方式,但是STL实现映射通常采用平衡二叉搜索树,更具体一些----红黑树。

一颗树由多个节点构成。一个Node保存一个关键字和对应的值,并且指向两个子节点。

若保存关键字值的Node成员的名字为first,二叉搜索树的基本规则是:
left->first < first && first < right->first

即,对每个节点,
    它的左子节点的关键字小于本节点的关键字;
    而且,本节点的关键字小于它的右节点的关键字。

这棵树仍然遵守每个节点的关键字大于它的左子节点、小于它的右子节点的规则:

显然,map的接口与vector和list是很相似的。最大的不同是在遍历时,map的元素类型为pair<Key, Value>。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值