小议C++里 set和map关联容器的用法

set容器

set容器是关键字的简单集合。特别适用于想快速知道某个元素在容器中是否出现情况

在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。set中元素的值不能直接被改变。set内部采用的是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树。

set具备的两个特点:

  • set中的元素都是排序好的
  • set中的元素都是唯一的,没有重复的

set容器中常用的方法

count()           用来查找set中某个某个键值出现的次数

这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了

insert(x)            向容器中插入元素x

erase(x)            删除容器中元素x

begin()        返回set容器的第一个元素    /   返回指向第一个元素的迭代器

end()      返回set容器的最后一个元素

clear()          删除set容器中的所有的元素

empty()     判断set容器是否为空

size()      返回当前set容器中的元素个数

具体编码应用:无重复字符的最长子串

//无重复字符的最长子串
class Solution {
public:
    int lengthOfLongestSubstring(string s) {    
        //滑动窗口方法[)左闭右开   [i,j)
        int n=s.size();
        set<char> st;
        int ans=0;
        int i,j;
        for( i=0,j=0;i<n && j<n; ){
            if(st.count( s[j] )==0 ){  //count()方法判断字符是否出现
                st.insert( s[j] );
                j++;
                ans=max(ans,j-i);
            }
            else{
                st.erase(s[i]);       //erase(x)方法删除容器中字符x
                i++;
            }
        }
        return ans;
    }
};

map容器

map提供一对一的数据处理,<key  ,  value>键值对,其类型可以自己定义,其中第一个成为关键字,第二个称为关键字的值。

map具备的两个特点:

  • map中的元素都是排序好的
  • map中关键字key不能修改,值value可以修改
  • iter->first;       //key值
  • iter->second; // value值

map容器中常用的方法

1、查找元素   find(x)

当所查找的关键x出现时,它返回数据所在对象的位置,如果沒有,返回iter与end()的值相同,

用于快速查找某个关键字是否出现在map容器中

2、map容器中插入元素

// 定义一个map对象
map<int, char> mp;
 
// 第一种 用insert函数插入pair
mp.insert(  pair<int, char>(0, ‘a’)  );
 
// 第二种 用insert函数插入value_type数据
mp.insert(  map<int, char>::value_type(1, 'b')  );
 
// 第三种 用"array"方式插入
mp[2] = 'c';

***注意***

以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,第一种和第二种在效果上是完成一样的,用insert方法插入数据(个人推荐不用记住第二种方法),但是在数据的插入上涉及到集合的唯一性这个问题,即当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组array方式就不同了,它可以覆盖以前该关键字对 应的值.

mp[2] = 'c';
mp.insert(  pair<int, char>(2, ‘a’)  );       //这条语句不执行
mp[2] = 'd';                                  //该语句执行,且改变关键字2的值为d

3、map的遍历

//迭代
map< string,int>::iterator iter;
for(iter = mp.begin(); iter != mp.end(); iter++)
    cout<<iter->first<<' '<<iter->second<<endl;//输出的是key value值

//数组形式的遍历   下标从1开始
int nSize = mp.size();    
//此处应注意,应该是 for(int nindex = 1; nindex <= nSize; nindex++)  
//而不是 for(int nindex = 0; nindex < nSize; nindex++)  
for(int nindex = 1; nindex <= nSize; nindex++)  
    cout<<mp[nindex]<<endl; 

//反向迭代
map<string,int>::reverse_iterator iter;
for(iter = mp.rbegin(); iter != mp.rend(); iter++)
    cout<<iter->first<<' '<<iter->second<<endl;


4、其它方法

    count()         返回指定元素出现的次数   

    begin()         返回指向map头部的迭代器

    end()           返回指向map末尾的迭代器

    rbegin()        返回一个指向map尾部的逆向迭代器

    rend()          返回一个指向map头部的逆向迭代器

    clear()        删除所有元素

    erase()         删除一个元素

    empty()         如果map为空则返回true

    size()          返回map中元素的个数

  具体编码应用:无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //优化的滑动窗口方法[)左闭右开,当遇见重复字符时,将i定位到最大的一位,而不需要逐渐增加i
        int n=s.size();
        int ans=0;
        int i,j;
        map<char, int> mp;
        for(i=0,j=0;j<n;j++){
            //元素存在了
            if(mp.find(s[j]) != mp.end()){
                i=max(i,mp.find(s[j])->second);
            }
            ans=max(ans,j-i+1);
            mp[s[j]]=j+1; //注意防坑
 //如果使用mp.insert(  pair<char ,int> (s[j],j+1)) 则无法更改关键值的值,导致算法运行失败
        }
        return ans;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值