STL(三)

目录

一、list容器

1.基本概念

 2.构造函数

3.赋值和交换

4. 大小操作

5.插入和删除

6.数据存取

7.反转和排序

二、set容器

1.构造和赋值

2.大小和交换

3.插入和删除

4.查找和统计

5.set和multiet的区别

6. pair对组创建

7.指定排序规则

(1)内置类型指定

(2)自定义类型指定

 三、map容器

1.构造和赋值

2. 大小和交换

3.插入和删除

4.查找和统计

5.排序


 一、list容器

1.基本概念

list将数据进行链式存储。链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。

链表的组成:链表由一系列结点组成。结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

list优点:采用动态存储分配,不会造成内存浪费和溢出;可以对任意位置进行插入删除元素。缺点:容器遍历速度没有数组快,占用空间比数组大。

STL中的链表是一个双向循环链表。 由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器。

list有一个重要的性质,插入操作和删除操作不会造成原有list迭代器的失效,这在vector是不成立的。

STL中List和vector是两个最常被使用的容器,各有优缺点

 2.构造函数

list构造方式同其他几个STL常用容器,熟练掌握即可。

3.赋值和交换

list赋值和交换操作能够灵活运用即可。

4. 大小操作

5.插入和删除

6.数据存取

list不能使用[]或at访问容器中的元素。原因是list本质是链表,不是用连续线性空间存储数据,迭代器也是不支持随机访问的。

7.反转和排序

对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序。

将Person自定义数据类型进行排序,Person有姓名、年龄、身高这三个属性。

8.士兵队列训练问题

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int n,nums;
void solve(list<int> &l,int key){
    int i=0;
    list<int>::iterator it=l.begin();
    while(it!=l.end()){//报完数以后才判断size是否小于3,而不是士兵小于3人以后立刻停止报数
        i++;
        if((i%key==0)){it=l.erase(it);}
        else{it++;}
    }
}
int main()
{
    while(cin>>n){
        for(int i=0;i<n;i++){
            cin>>nums;
            list<int> l;
            for(int i=1;i<=nums;i++)
                l.push_back(i);
            while(l.size()>3){
                solve(l,2);
                if(l.size()<=3)//报完数以后判断一下 如果不超过3人则退出循环
                    break;
                solve(l,3);
            }
        for(list<int>::iterator it=l.begin();it!=l.end();it++)
            cout<<*it<<" ";
        cout<<endl;
    }
    }

    return 0;
}

二、set容器

1.构造和赋值

所有元素在插入容器时自动被排序。set/multiset属于关联式容器,底层结构是用二叉树实现的。

set不允许容器中有重复的元素,multiset允许容器中有重复的元素。

2.大小和交换

set不支持resize,因为如果resize过长,以0或指定数填充和set不允许重复的特点相矛盾。

3.插入和删除

insert插入,erase删除,clear清空

4.查找和统计

5.set和multiet的区别

set不可以插入重复数据,而multiset可以;set插入数据的同时会返回插入结果,表示插入是否成功;multiset不会检测数据,因此可以插入重复数据。

6. pair对组创建

成对出现的数据,利用对组可以返回两个数据。

7.指定排序规则

(1)内置类型指定

利用仿函数改变排序规则,仿函数是定义了一个含有operator()成员函数的对象。

目前不需要了解这个原理,知道这么用就行了。

(2)自定义类型指定

8.{A} + {B}

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int main()
{
    int key;
    while(cin>>n>>m){
        set<int> s;

        for(int i=0;i<n;i++){
            cin>>key;
            s.insert(key);
        }
        for(int i=0;i<m;i++){
            cin>>key;
            s.insert(key);
        }
        for(set<int>::iterator it=s.begin();it!=s.end();it++)
            cout<<*it<<" ";
        cout<<endl;
    }
    return 0;
}

9. MANAGER

 

可以看出题目中的队列需要有自动排序的功能,且允许有重复元素。 

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int m,n;
multiset<int> s,arr;
int main()
{
    while(cin>>m>>n){
        char a;
        int key=1,nums=0,t,b;
        s.clear();
        arr.clear();
        for(int i=0;i<n;i++){
            cin>>t;
            arr.insert(t);//移除列表
        }
        while(cin>>a&&a!='e'){
            if(a=='a'){
                cin>>b;s.insert(b);
            }
            else if(a=='r'){
                nums++;
                if(nums==*arr.begin()&&s.empty()){//移除请求的序号在列表中且但s为空
                    cout<<"-1"<<endl;
                    arr.erase(arr.begin());
                    continue;
                }
                if(key==1){
                    if(nums==*arr.begin()){cout<<*s.begin()<<endl;arr.erase(arr.begin());}
                    s.erase(s.begin());//移除成本最低的
                }
                else{
                    if(nums==*arr.begin()){cout<<*(--s.end())<<endl;arr.erase(arr.begin());}
                    s.erase(--s.end());//移除成本最高的
                }

            }
            else{
                cin>>b;key=b;
            }
        }
        cout<<endl;
    }
    return 0;
}

 三、map容器

map中所有元素都是pair。pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)。所有元素都会根据元素的键值自动排序。

map/multimap属于关联式容器,底层结构是用二叉树实现。

优点:可以根据额key值快速找到value值。

map和multimap区别:map不允许容器中有重复的key值,multimap允许有重复的key值。

1.构造和赋值

map中所有元素都是成对出现,插入数据时要使用对组。

2. 大小和交换

统计大小size;判空empty;交换swap

3.插入和删除

map插入方式很多种,记住其一即可

4.查找和统计

 

5.排序

同set容器默认以key值升序,利用仿函数排序。(以下代码operator前少了个bool)

6. Hardwood Species

 

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int m,n;
map<string,int> M;
string str;
int main()
{
    while(getline(cin,str)){
        if(str.empty())
            break;
        if(M[str])
            M[str]+=1;
        else M[str]=1;
    }
    int sum=0;
    for(map<string,int>::iterator it=M.begin();it!=M.end();it++)
        sum+=it->second;
    for(map<string,int>::iterator it=M.begin();it!=M.end();it++){
        double percentage = (double)(it->second) / sum * 100.0;
        cout<<it->first<<" "<<fixed <<setprecision(4)<<percentage<<endl;
    }
    return 0;
}

7.Double Queue

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int a,b,c;
int main()
{
    map<int,int> m;
    while(cin>>a&&a!=0){
        if(a==1){
            cin>>b>>c;
            m.insert(make_pair(c,b));//可以假设列表中没有其他相同客户或相同优先级的请求
        }
        else{
            if(m.empty()){cout<<"0"<<endl;continue;}
            if(a==2) {cout<<(--m.end())->second<<endl;m.erase(--m.end());}
            else {cout<<m.begin()->second<<endl;m.erase(m.begin());}
        }
    }
    return 0;
}

8. 水果

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int n,m,nums;
string a,b;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        map<string, map<string,int> > M;
        cin>>m;
        for(int i=0;i<m;i++){
            cin>>a>>b>>nums;
           map<string,map<string,int> >::iterator pos=M.find(b);//查找有无这个地名
            if(pos!=M.end()){
                map<string,int>::iterator pos1=(pos->second).find(a);//查找这个地名中有无这个水果
                if(pos1!=(pos->second).end())pos1->second+=nums;//有水果再加上数量
                else (pos->second).insert(make_pair(a,nums));//无水果等于数量
            }else{
                map<string,int> M1;M1.insert(make_pair(a,nums));//没有这个地名,插入数据
                M.insert(make_pair(b,M1));
            }
        }
        for(map<string, map<string,int> >::iterator it=M.begin();it!=M.end();it++){//遍历
            cout<<it->first<<endl;
            for(map<string,int>::iterator it1=(it->second).begin();it1!=(it->second).end();it1++){
                cout<<"   |----"<<it1->first<<"("<<it1->second<<")"<<endl;
            }
        }
    }
    return 0;
}

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值