STL——算法

懵懂的女人 提交于 2020-01-06 15:30:33

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

以下内容大多摘自《C++标准程序库》

算法实例

STL提供了一些标准算法,包括搜寻、排序、拷贝、重新排序、修改、数值运算等。算法并不是容器类别的成员函数,而是一种搭配迭代器使用的全局函数。

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

using namespace std;

int main() {
    vector<int> coll;
    vector<int>::iterator pos;
    //coll.push_back(2);
    coll.push_back(5);
    coll.push_back(4);
    coll.push_back(1);
    coll.push_back(6);
    coll.push_back(3);

    pos = min_element(coll.begin(),coll.end());    //寻找最小值
    cout << "min:" << *pos << endl;
    pos = max_element(coll.begin(), coll.end());//寻找最大值
    cout << "max:" << *pos << endl;

    sort(coll.begin(),coll.end());  //排序
    cout << "sort:";
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        cout << *pos << ' ' ;
    }
    cout << endl;       //这里输出的是  1 2 3 4 5 6
    pos = find(coll.begin(),coll.end(), 3);   //找到值为3的第一个元素
    cout << "find:";
    cout << *pos << endl;   

    reverse(pos,coll.end());  //反转pos及以后的所有元素,因为前面把pos知道了3的位置,所以这样操作就是反转3到以后的元素,前面的find()就是用来打辅助的
    
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        cout << *pos << ' ';
    }
    cout << endl;
    system("pause");
}

最后输出:

min:1
max:6
sort:1 3 4 5 6
find:3
1 6 5 4 3

区间

为了使用算法,我们一般将区间首尾当做两个参数来传给算法,而不是一口气将整个容器传递进去。这里面调用者必须保证两个参数定义出来的区间是有效的,也就是从起点出发,逐一前进,能够到达终点,也就是说,必须确保两个迭代器隶属于同一容器,且前后放置必须正确。同时,所有算法处理的都是半开区间[begin,end).

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main() {
    list<int>coll;
    list<int>::iterator pos;

    for (int i = 20; i <= 40; ++i) {
        coll.push_back(i);
    }
    pos = find(coll.begin(),coll.end(),3);
    reverse(pos,coll.end());

    list<int>::iterator pos25, pos35;   //这里声明了区间的前后两个迭代器
    pos25 = find(coll.begin(), coll.end(), 25);
    
    pos35 = find(coll.begin(), coll.end(), 35); //这里使得两个迭代器都属于同一个容器。

    cout << "pos35:" << *pos35 << endl;
    cout << "max:" << *max_element(pos25, pos35) << endl;
    cout << "max:" << *max_element(pos25, ++pos35) << endl;
    system("pause");

}

结果为:

pos35:35
max:34
max:35

意思是说,pos35已经指向了35的位置,所以输出时,输出的值是35,但是作为区间传入算法时,由于是半开区间,前面是闭区间,后面是开区间,所以该算啊并不包括35,所以最后的结果是max=34,需要让后面的参数加一才能得到我们所想要的35.

值得一提的是,本次使用的是list,是双向迭代器,只能以++来获得pos35的下一个位置,但如果是vector或者deque等随机存取迭代器,则可以写pos35+1.因为随机存取迭代器允许迭代器算数运算。

确定两个区间参数谁前谁后可以通过如下方法确定:

pos25=find(coll.begin(),coll.end(),25);

pos35=find(coll.begin(),pos25,35);

if(pos25!=pos35){

//pos35在pos25之前(说明该上面那个式子pos35在到达pos25之前就已经找到了值)

}

else{//说明pos35在开始到pos25之间并没有找到值(此时pos35已经指到了pos25)

    pos35=find(pos25,coll.end(),);//让pos35从pos25开始往后面找,这个是为了判断是否pos25=pos35

    if(pos35!=pos25){

        //说明pos35在pos25后面了

}

else{

//说明两个相等

}

}

处理多个区间

有数个算法可以同时处理多个区间,通常必须先设定第一个区间的起点和终点,至于其他区间,只需要设定起点即可,终点通常可以由第一区间的元素数量推导出来,但是这样就需要确保第二个或者其他区间所拥有的元素个数,至少和第一区间内的元素个数相同。

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;
int main() {
    list<int>coll1;
    vector<int>coll2;//刚开始这样定义出来coll2是空的,它需要先添加新的元素然后再赋值

    for (int i = 1; i <= 9; ++i) {
        coll1.push_back(i);
    }
//    copy(coll1.begin(), coll1.end(), coll2.begin());   //这样copy是有问题的,因为coll2没有足够的元素供copy
    coll2.resize(coll1.size());//这是一种方法,resize可以改变元素个数,来保证第二个元素跟第一个元素一样多
    copy(coll1.begin(),coll1.end(),coll2.begin());
    deque<int>coll3(coll1.size());//这也是一种方法,在初始化的时候就已经定义了元素的个数,并且已经将这些元素初始化为0了。
    copy(coll1.begin(), coll1.end(), coll3.begin());
    system("pause");

}

以上两种方法都产生了新元素,并对元素进行了初始化(初始化为零)。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!