【C++】数据结构的恶龙set和map来了~(下)

简介: 【C++】数据结构的恶龙set和map来了~(下)


三.题目练习



力扣:前K个高频单词

力扣链接:力扣


915c1d3ddd7240c0b9cbbd7d575df8c0.png


看到这道题大家应该首先想到的就是map了吧,毕竟题目已经很明显的说了KV键值对,下面我们说一下思路:首先我们用mp的[]功能统计出每个单词出现的次数以及对应的每个单词,然后我们将前K个这样的单词放入向量中,然后打印即可:


class Solution {
public:
    struct compare
    {
        bool operator()(const pair<string,int>& k1,const pair<string,int>& k2)
        {
            return k1.second>k2.second;
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int> mp;
        for (auto& e:words)
        {
            mp[e]++;
        }
        vector<pair<string,int>> v(mp.begin(),mp.end());
        sort(v.begin(),v.end(),compare());
        vector<string> result;
        for (int i = 0;i<k;i++)
        {
            result.push_back(v[i].first);
        }
        return result;
    }
};

首先我们用一个map来计算单词以及单词的次数,然后用一个vector来保存这些键值对(vector的类型一定是pair),然后我们用sort函数排序vector,由于pair默认的排序方式是以K值进行排序的,所以我们必须写一个仿函数来用键值对中的value值比较,比较完成后我们用另一个vector来接收前K个字符串,最后我们只需要返回string即可所以是v[i].first。但是如果我们发现没有通过,如下图:


1758f2ffb3d7423aa155435f5c629c5b.png


发现错误的原因是单词的顺序不对,当出现相同次数的单词需要用字典序来排序,所以这个时候我们就想到了排序的稳定性,如果一个排序稳定的话相同的值的相对顺序是不变的,本题给的测试列表本来也是按照字典序排好的,所以我们直接换一个稳定排序就解决了,在算法中有一个稳定排序:


f650757d2acb4d0a97e7aa788308773c.png


下面我们就换上这个稳定排序:


223107920ebd4f21a7e81274ae7f21b3.png


这样我们就通过了,那么如果我们还有其他办法解决刚刚的顺序问题吗?答案是当然有,要知道我们写仿函数的目的就是为了控制比较方式:


70341f4f730a4154a27e4c862b210ae6.png


当然我们也可以用我们刚刚学的的set来进行比较,因为我们的set和map也是支持控制比较方式的:


class Solution {
public:
    struct compare
    {
        bool operator()(const pair<string,int>& k1,const pair<string,int>& k2) const
        {
            return k1.second>k2.second||(k1.second==k2.second)&&k1.first<k2.first;
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int> mp;
        for (auto& e:words)
        {
            mp[e]++;
        }
        set<pair<string,int>,compare> st(mp.begin(),mp.end());
        vector<string> v;
        auto it = st.begin();
        while (k--)
        {
            v.push_back(it->first);
            ++it;
        }
        return v;
    }
};


在这里大家要注意:

4e44fb0d340540589c113209a8ad88ae.png


set中对于仿函数用的是模板,模板我们必须传类型所以我们写set的时候写的compare,像sort就不一样了:


22da5cf5220d4b2f952deb0f3885e43d.png


我们可以看到sort中传的是仿函数对象,所以我们使用的时候用了匿名对象compare().当然上面的代码中我们写仿函数一定要在后面加上const,因为有些测试用例会有const对象,如果没写const会编译报错。


总结



学数据结构就如同我们打怪升级一般,从一开始的单链表到二叉树,每一次的难度都是层层递进的,到了map这边下一篇我们要讲的AVL树难度要比二叉树搜索树难了不止一点,但是只要大家有着面对困难打败困难的心就一定可以成为屠龙勇士~

目录
相关文章
|
1月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
141 1
|
4月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
368 1
|
30天前
|
存储 算法 容器
set_map的实现+set/map加持秒杀高频算法题锻炼算法思维
`set`基于红黑树实现,支持有序存储、自动去重,增删查效率为O(logN)。通过仿函数可自定义排序规则,配合空间配置器灵活管理内存。不支持修改元素值,迭代器失效需注意。`multiset`允许重复元素。常用于去重、排序及查找场景。
|
5月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
308 121
|
8月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
229 2
|
5月前
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
247 0
|
5月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
68 0
|
5月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
241 0
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
273 59

热门文章

最新文章