STL4.1 算法

STL4.1 算法

即函数模板,用来对容器操作,在algorithm\numeric中定义

一、不变序算法

不会改变算法作用的容器或对象,适用于所有容器
1.常见算法

  • min,max,min_element,max_element
  • for_each
  • count,count_if
  • find,find_if,find_first_of,adjacent_find
  • find_end,search
  • search_n
  • equal,mismatch
  • lexicographical

2.例

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
void print(int v){
    cout<<"<"<<v<<">";
}
bool lessthan4(int n){
    return n<4;
}
int main(){
    cout<<"1)"<<min(3,4)<<" "<<max(5,6)<<endl;
    int a[9]={1,2,3,4,5,3,4,4,4};
    cout<<"2)"<<*min_element(a,a+9)<<" "<<*max_element(a,a+9)<<endl;
    cout<<"3)"<<count(a,a+9,4)<<" "<<count_if(a,a+9,lessthan4)<<endl;
    list<int> lst(a,a+9);
    int b[2]={4,3};
    vector<int> v(b,b+2);
    list<int>::iterator p;
    p=find_first_of(lst.begin(),lst.end(),b,b+2);//找到4,3中任一元素
    cout<<"4)"<<distance(lst.begin(),p)<<endl;
    reverse(v.begin(),v.end());
    int* ptr=find_end(a,a+9,v.begin(),v.end());
    cout<<"5)"<<distance(a,ptr)<<endl;
    p=adjacent_find(lst.begin(),lst.end());
    cout<<"6)"<<*p<<" "<<distance(lst.begin(),p)<<endl;
    p=search(lst.begin(),lst.end(),v.begin(),v.end());
    cout<<"7)"<<distance(lst.begin(),p)<<endl;
    ptr=search_n(a,a+9,2,4);
    cout<<"8)"<<distance(a,ptr)<<endl;
    cout<<boolalpha;//将true,false以字符串的形式输出
    cout<<"9)"<<equal(v.begin(),v.end(),a+2)<<endl;

    int c[6]={1,2,3,9,7,8};
    pair<int*,int*> result;
    result=mismatch(c,c+6,a);
    cout<<"10)"<< *(result.first) <<" "<<*result.second<<endl;
    cout<<"11)"<<lexicographical_compare(a,a+9,c,c+6)<<endl;
    for_each(a,a+3,print);
    return 0;
}
结果:
1)3 6
2)1 5
3)4 4
4)2
5)5
6)4 6
7)2
8)6
9)true
10)9 4
11)true
<1><2><3>

二、变值算法

1.修改源区间或目标区间中元素的值,值被修改的区间不应该属于关联容器,否则会改变有序性
2.例

#include <iostream>
#include <list>
#include<iterator>
#include <vector>
#include <algorithm>
using namespace std;
void modify(int & lst){lst*=lst;}
int square(int n){return n*n;}
int zero(){return 0;}
int one(){return 1;}
bool even(int n){return ! (n%2);}
int main(){
    int a[6]={1,2,3,4,5,6};
    int b[6];
    copy(a,a+6,b);
    ostream_iterator<int> oit(cout,",");
    cout<<"1)";copy(b,b+6,oit);cout<<endl;

    copy_backward(b,b+4,b+5);//源区间和目标区间有重叠,为了保证正确复制,倒着复制
    cout<<"2)";copy(b,b+6,oit);cout<<endl;

    list<int> lst(5);//预先开辟空间,否则复制操作会出错
    transform(a,a+5,lst.begin(),square);
    cout<<"3)";copy(lst.begin(),lst.end(),oit);cout<<endl;//a中元素没有改变

    swap_ranges(lst.begin(),lst.end(),b);
    cout<<"4)";copy(lst.begin(),lst.end(),oit);cout<<endl;//交换等长区间的内容

    fill(b,b+6,0);
    fill_n(b+2,3,1);
    cout<<"5)";copy(b,b+6,oit);cout<<endl;

    copy(a,a+6,b);
    generate(b,b+6,zero);
    generate_n(b+1,3,one);
    cout<<"6)";copy(b,b+6,oit);cout<<endl;

    replace(b,b+6,1,3);
    cout<<"7)";copy(b,b+6,oit);cout<<endl;
    replace_if(b,b+6,even,11);
    cout<<"8)";copy(b,b+6,oit);cout<<endl;

    replace_copy(a,a+6,b,3,30);
    cout<<"9)";copy(b,b+6,oit);cout<<endl;
    replace_copy_if(a,a+6,b,even,7);
    cout<<"10)";copy(b,b+6,oit);cout<<endl;
    return 0;
}
结果:
1)1,2,3,4,5,6,
2)1,1,2,3,4,6,
3)1,4,9,16,25,
4)1,1,2,3,4,
5)0,0,1,1,1,0,
6)0,1,1,1,0,0,
7)0,3,3,3,0,0,
8)11,3,3,3,11,11,
9)1,2,30,4,5,6,
10)1,7,3,7,5,7,

例子中copy的用法:

template <class _II,class _OT> _OI copy(_II _F,_II _L,_OT _X)for(;_F!=_L;++_X,++_F)
		*_X=*_F;
	return (_X)
}

	template<class T>
    class myostream_iteraotr{
    private:
        ostream &os;//这里必须是ostream&
        /*ostream os 不可以
        因为ostream设计上是一个基类,它抽象了底层的行为,它本身什么功能都没有,当然不允许构造实例。
        ostream *os = new ofstream();
        作为基类指针完全可以。*/
        string s;
    public:
        myostream_iteraotr(ostream &ot,string x):os(ot),s(x){}
        void operator ++(){};
        myostream_iteraotr & operator *(){
            return *this;//返回自己本身,而不是自己的指针
        }
        myostream_iteraotr & operator=(const T x){
            os<<x<<s;return *this;
        }
    };

三、删除算法

1.工作原理:
将应该删除的元素看成空位,将剩余元素从后往前移动,依次去填充这些空位,没有被填充的空位保持原来的值不变
不作用于关联容器
2.例

#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<iterator>
using namespace std;
bool lessthan4(int n){
    return n<4;
}
int main(){
    int m[5]={1,2,3,2,5};
    ostream_iterator <int> oit(cout,",");
    int *q=remove(m,m+5,2);
    cout<<"1)";copy(m,m+5,oit);cout<<endl;
    cout<<"2)"<<q-m<<endl;

    int a[5]={1,2,3,2,5};
    int b[6]={1,2,3,2,5,6};
    int c[6]={0,0,0,0,0,0};
    remove_if(b,b+6,lessthan4);
    cout<<"3)";copy(b,b+6,oit);cout<<endl;

    int *p=remove_copy(a,a+5,c,2);
    cout<<"4)";copy(a,a+5,oit);cout<<" "<<p-c<<endl;
    cout<<"5)";copy(c,c+6,oit);cout<<endl;
    
    memset(c,0,sizeof(c));
    remove_copy_if(a,a+5,c,lessthan4);
    cout<<"6)";copy(c,c+6,oit);cout<<endl;

    int d[7]={1,2,2,2,3,3,4};
    vector<int> v;
    v.insert(v.begin(),d,d+7);
    unique(d,d+7);
    cout<<"7)";copy(d,d+7,oit);cout<<endl;

    memset(d,0,sizeof(d));
    unique_copy(v.begin(),v.end(),d);
    cout<<"8)";copy(d,d+7,oit);cout<<endl;

    return 0;
}
结果:
1)1,3,5,2,5,
2)3
3)5,6,3,2,5,6,
4)1,2,3,2,5, 3
5)1,3,5,0,0,0,
6)5,0,0,0,0,0,
7)1,2,3,4,3,3,4,
8)1,2,3,4,0,0,0,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值