24.map和set的使用

一、序列式容器和关联式容器

序列式容器:逻辑结构为线性序列的容器,两个位置所存放的数据一般没有紧密关系,例如两个位置交换一下,逻辑结构没有改变。

关联式容器:通常是非线性结构(堆例外),两个位置存放数据有紧密的关联关系,交换一下逻辑结构就改变了。

常见的序列式容器:string,vector,list,deque,array,forward_list

常见的关联式容器:map/set系列和unordered_map/unordered_set系列

map(key/value)和 set(key),底层是红黑树,红黑树是一颗平衡二叉搜索树。 

易错点1:

map可以是升序,也可是降序,默认情况下是升序,如果需要降序,需要用户在实例化map时指定比较规则。

set中可以存储键值对,实例化set时,将set中元素类型设置为pair即可。

二、set的介绍

template < class T , // set::key_type/value_type
class Compare = less<T>, // set::key_compare/value_compare
class Alloc = allocator<T> // set::allocator_type
> class set;
1.set默认T支持小于比较,若不支持或要改变比较逻辑要显式传仿函数。
2.set增删查时间复杂度是O(logN),迭代器遍历走的是搜索树的中序,即有序序列。

set的构造函数

empty (1)
explicit set (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
range (2)
template <class InputIterator>set (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
copy (3)
set (const set& x);

1)默认构造

2)迭代器区间构造

3)拷贝构造

iteratora bidirectional iterator to value_typeconvertible to const_iterator
const_iteratora bidirectional iterator to const value_type
set的迭代器是双向迭代器。

 Modifiers:

insert:

// 单个数据插⼊,如果已经存在则插⼊失败
pair<iterator, bool > insert ( const value_type& val);
// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template < class InputIterator >
void insert (InputIterator first, InputIterator last);

erase: 

(1)
iterator  erase (const_iterator position);
(2)
size_type erase (const value_type& val);
(3)
iterator  erase (const_iterator first, const_iterator last);
1)删除迭代器位置,返回删除后中序遍历下一个位置的迭代器
2)删除val,删除了返回1,没有删除返回0
3)删除一段迭代器区间
注:erase()一个迭代器后,迭代器就失效了

原因:
1.如果该节点是叶子节点,或者左右子树有一为空的节点,会被直接删除,导致野指针的问题,迭代器失效了。
2.如果该节点的左右子树都不为空,会使用替换删除,虽然该节点没有被释放掉,但是意义变了,也认为迭代器失效了。

find和count 

// 查找 val ,返回 val 所在的迭代器,没有找到返回 end()
iterator find ( const value_type& val);
// 查找 val ,返回 Val 的个数,通常用于查找
size_type count ( const value_type& val) const ;

lower_bound和upper_bound 

// 返回大于等val位置的迭代器

iterator lower_bound (const value_type& val) const;
// 返回大于val位置的迭代器
iterator upper_bound (const value_type& val) const;

void test_set1()
{set<int> s({ 10,20,30,40,50,60,70,80,90,100 });//若要得到[20,55]区间的值//lower_bound闭区间,upper_bound开区间set<int>::iterator bit = s.lower_bound(20);set<int>::iterator eit = s.upper_bound(50);while(bit != eit){cout << *bit << " ";++bit;}cout << endl;
}

lower_bound返回大于等于key的值,upper_bound返回大于key的值。

mutiset和set的区别:

 find的示例,特别注意,++mit是按中序遍历走,有序序列的方式走,不会错过。

和set不同的是,count不只是返回0和1,而是可能有多个,erase删除key值也是删除所有key值。

set的使用场景(两个OJ题):

349. 两个数组的交集 - 力扣(LeetCode)
思路:使用两个set达到排序和去重的效果,然后遍历两个set,输出有序序列,如果两个值相等,vector尾插这个值,两个迭代器都走;如果两个值不相等,值小的迭代器走,因为值大的后面没有比值小的更小了。

拓展:若所求的是差集,那么遇到相等的跳过,两个迭代器都走;如果两个值不相等,值小的vector尾插这个值,值小的迭代器走,因为值大的后面没有比值小的更小了,值小的就是差集;如有一迭代器走完了,另一迭代器没走完的部分全是差集。

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> s1,s2;for(const auto& ch:nums1){s1.insert(ch);}for(const auto& ch:nums2){s2.insert(ch);}vector<int> v;set<int>::iterator it1 = s1.begin();set<int>::iterator it2 = s2.begin();while(it1!=s1.end() && it2!=s2.end()){if(*it1==*it2){v.push_back(*it1);++it1;++it2;}//小的走,因为大的后面没有比这小的了else if(*it1>*it2){++it2;}else{++it1;}}return v;}
};

 142. 环形链表 II - 力扣(LeetCode)

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

对于环形链表,用C语言解决的话有两种方式:

定义两个指针,慢指针一次走1步,快指针一次走2步或者3步,它们一定会相遇在环内部的一个节点,将这个节点记录为相遇节点。

1.在相遇节点处断开,然后就转化成了链表相交的问题,长链表从头走到和短链表一样长的位置,然后找到相交节点,由于题目本身不让破坏节点,最后相遇节点链接回去。

2.定义两个指针一个从头开始走,另一个从链表相交位置开始走,它们一定会在入口节点相遇,证明法。

对于C++,简单很多,只需要将定义一个节点指针cur从头开始走,插入到set中,直到set插入失败,即回到环的开始节点了,此时插入失败的节点指针就是入环的第一个节点。

class Solution {
public:ListNode *detectCycle(ListNode *head) {set<ListNode*> s;ListNode* cur = head;while(cur){pair<set<ListNode*>::iterator,bool> ret = s.insert(cur);if(ret.second==false)return cur;cur = cur->next;}return nullptr;}
};

三、map系列的使用

map的声明

map底层也是红黑树,key-value模型,按key比较。

template < class Key,                                     // map::key_typeclass T,                                       // map::mapped_typeclass Compare = less<Key>,                     // map::key_compareclass Alloc = allocator<pair<const Key,T> >    // map::allocator_type> class map;

map增删查改的效率是O(logN)。

pair结构

template <class T1, class T2> struct pair;
typedef pair<const Key, T> value_type;
template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair(): first(T1()), second(T2()){}pair(const T1& a, const T2& b): first(a), second(b){}template<class U, class V>pair (const pair<U,V>& pr): first(pr.first), second(pr.second){}
};
template <class T1,class T2>
inline pair<T1,T2> make_pair (T1 x, T2 y)
{return ( pair<T1,T2>(x,y) );
}
member typedefinitionnotes
key_typeThe first template parameter (Key)
mapped_typeThe second template parameter (T)
value_typepair<const key_type,mapped_type>

在map中,pair<const key_value,mapped_typed>被重命名为了value_type,第一个是const key,第二个是value,用了一个结构pair封装。

map的构造函数

// empty (1) ⽆参默认构造
explicit map ( const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
// range (2) 迭代器区间构造
template < class InputIterator >
map (InputIterator first, InputIterator last,
const key_compare& comp = key_compare (),
const allocator_type& = allocator_type ());
// copy (3) 拷⻉构造
map ( const map& x);
// initializer list (5) initializer 列表构造
map (initializer_list<value_type> il,
const key_compare& comp = key_compare (),
const allocator_type& alloc = allocator_type ());
// 迭代器是⼀个双向迭代器
iterator -> a bidirectional iterator to const value_type
// 正向迭代器
iterator begin ();
iterator end ();
// 反向迭代器
reverse_iterator rbegin ();
reverse_iterator rend ();

map具体案例1: 

void test_map1()
{map<string, string> m({ {"sort","排序"},{"left","左边"} });//多参数的隐式类型转换,C++11// "right","右边"隐式类型转换成string//{string,string}隐式类型转换成pair<const string,string>m.insert({ "right","右边" });//利用make_pair创建一个pair<const string,string>的匿名对象m.insert(make_pair("right", "右边"));
}

map可以用初始化列表初始化,C++11支持多参数的隐式类型转换,用{}括起来。

map具体案例2:

void test_map2()
{map<string, string> m({ {"sort","排序"},{"left","左边"} });map<string, string>::iterator it = m.begin();while (it != m.end()){//注意it所指向的对象是一个pair结构的,不能直接解引用访问cout << it->first << ":" << it->second << endl;++it;}cout << endl;
}

 注意map的迭代器指向的是一个pair结构,不能直接解引用访问。

map具体案例3:

void test_map3()
{map<string, string> m({ {"sort","排序"},{"left","左边"} });//insert一个已经存在的key,不会做任何修改m.insert({ "left","剩余" });for (const auto& ch : m){cout << ch.first << ":" << ch.second << endl;}cout << endl;
}

易错点:insert一个已经存在的key值,不会做任何修改。

map的增删查接口:

Member types
key_type -> The first template parameter (Key)
mapped_type -> The second template parameter (T)
value_type -> pair<const key_type,mapped_type>
// 单个数据插⼊,如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
pair<iterator,bool> insert (const value_type& val);
// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find (const key_type& k);// 查找k,返回k的个数
size_type count (const key_type& k) const;// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);
// 删除k,k存在返回0,存在返回1
size_type erase (const key_type& k);
// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);// 返回⼤于等k位置的迭代器
iterator lower_bound (const key_type& k);
// 返回⼤于k位置的迭代器
const_iterator lower_bound (const key_type& k) const;

map具体案例4和5:

void test_map4()
{// 利用find和iterator修改功能,统计水果出现的次数string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉" };map<string, int> m;//插入数据for (const string& s : arr){m.insert({ s,0 });}map<string, int>::iterator it;//再次遍历一遍arr// 用find查找对应key位置的迭代器,使value++for (const string& s : arr){it = m.find(s);it->second++;}for (const auto& ch : m){cout << ch.first << ":" << ch.second << endl;}cout << endl;
}

这里利用find和iterator修改功能,统计水果出现的次数。但是这种写法太麻烦了,要遍历两便arr数组可改为以下写法:

void test_map5()
{string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉" };map<string, int> m;//operator[]有插入,查找,修改三种功能//key不存在,插入数据,返回value的引用,修改数据//key存在,根据key查找,返回value的引用,修改数据for (const string& s : arr){m[s]++;}for (const auto& ch : m){cout << ch.first << ":" << ch.second << endl;}cout << endl;
}

operator[]的作用:插入,查找,修改。

1.key不存在,插入(期间会调用value的默认构造),返回value的引用。

2.key存在,查找,返回value的引用。

pair<iterator, bool > insert ( const value_type& val);
mapped_type& operator [] ( const key_type& k);
// operator 的内部实现
mapped_type& operator [] ( const key_type& k)
{
        // 1、如果 k 不在 map 中, insert 会插⼊ k mapped_type 默认值,同时 [] 返回结点中存储
 mapped_type值的引⽤,那么我们可以通过引⽤修改返映射值。所以 [] 具备了插⼊ + 修改功能
        // 2、如果 k map 中, insert 会插⼊失败,但是 insert 返回 pair 对象的 first 是指向 key 结点的 迭代器,返回值同时 [] 返回结点中存储 mapped_type 值的引⽤,所以 [] 具备了查找 + 修改的功能
        pair<iterator, bool > ret = insert ({ k, mapped_type () });
        iterator it = ret.first;
        return it->second;
}
可以看到,operator[]内部调用insert,insert返回一个pair<iterator,bool>的结构,插入成功,pair.second为true,反之为false,pair.first为key位置所在的迭代器,operator[]返回该迭代器位置的value的引用。

mutimap和map的区别:

void test_mutimap1()
{multimap<string, string> m({ {"sort","排序"},{"left","左边"} });m.insert({ "left","剩余" });for (const auto& s : m){cout << s.first << ":" << s.second << endl;}cout << endl;m.erase("left");for (const auto& s : m){cout << s.first << ":" << s.second << endl;}cout << endl;
}

multimap允许key值冗余,insert一定成功。

erase()删除所有key。

equal_range() 

pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
pair<iterator,iterator>             equal_range (const key_type& k);

返回pair结构封装的迭代器区间,左闭右开。

两个OJ题:

138. 随机链表的复制 - 力扣(LeetCode)

若按C语言做,思路如下:

随机指针是原链表节点之间的关系,要使拷贝链表也具有这种关系,在每个原链表节点位置将拷贝节点插入到原链表节点的后面。

1)遍历一遍原链表,在每个原链表节点后复制一个节点插入到节点后面

2)再次遍历一遍链表,复制随机指针

3)再次遍历一遍链表,将复制链表取下来

按C++做,思路如下:

定义一个map<ListNode*,ListNode*>,key存原链表节点指针,value存现拷贝链表的指针。这样原链表节点的映射关系,拷贝链表也有了。

1)遍历一遍原链表,原链表指针作为key插入,new出来的拷贝链表指针的val和next赋值为原链表节点中对应的值

2)遍历两个链表,将节点指针插入进map

3)遍历一遍map,如果key->random为nullptr,value->random也为nullptr;如果key->random不为空,value->random = map[key->random]; 。

class Solution {
public:Node* copyRandomList(Node* head) {map<Node*,Node*> m;Node* cur = head;Node *copyhead,*tail;copyhead = tail = nullptr;//1.复制链表的值和next指针while(cur){Node* newnode = new Node(cur->val);if(copyhead==nullptr){tail = copyhead = newnode;}else{tail->next = newnode;tail = tail->next;}cur = cur->next;}//2.插入到map中cur = head;Node* copycur = copyhead;while(cur && copycur){m.insert({cur,copycur});cur = cur->next;copycur = copycur->next;}//3.复制random指针map<Node*,Node*>::iterator it = m.begin();while(it!=m.end()){if(it->first->random==nullptr){it->second->random = nullptr;}else{it->second->random = m[it->first->random];}++it;}return copyhead;}
};

思路1:将单词插入map中统计单词出现的次数,然后转入vector,对vector按次数排序,取出vector里的前k个高频单词。

注意点:map中默认是按单词string排了字典序,因此用vector排序时:

1)用稳定的排序。

2)使用sort,比较逻辑中特殊处理:对于出现次数相同的单词按字典序比较。

思路2:将单词插入map中统计单词出现的次数,然后转入priority_queue,比较逻辑特殊处理:对于出现次数相同的单词按字典序比较,取出priority_queue的前k个高频单词。

第一种:

class Solution {
public:struct great{bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){return p1.second > p2.second;}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> m;for(const string& s:words){//若不存在,插入,返回插入位置value的引用//若存在,查找,返回key位置value的引用m[s]++;}//转入vector中vector<pair<string,int>> v(m.begin(),m.end());//按降序排列stable_sort(v.begin(),v.end(),great());vector<string> ret;for(size_t i = 0;i<k;++i){ret.push_back(v[i].first);}return ret;}
};

第二种:

class Solution {
public:struct great{bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){return p1.second > p2.second || (p1.second==p2.second && p1.first < p2.first);}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> m;for(const string& s:words){//若不存在,插入,返回插入位置value的引用//若存在,查找,返回key位置value的引用m[s]++;}//转入vector中vector<pair<string,int>> v(m.begin(),m.end());//按降序排列sort(v.begin(),v.end(),great());vector<string> ret;for(size_t i = 0;i<k;++i){ret.push_back(v[i].first);}return ret;}
};

第三种:

class Solution {
public:struct less{bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){return p1.second < p2.second || (p1.second==p2.second && p1.first > p2.first);}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> m;for(const string& s:words){//若不存在,插入,返回插入位置value的引用//若存在,查找,返回key位置value的引用m[s]++;}//转入priority_queue中priority_queue<pair<string,int>,vector<pair<string,int>>,less> q(m.begin(),m.end());vector<string> ret;for(size_t i = 0;i<k;++i){ret.push_back(q.top().first);q.pop();}return ret;}
};

注意正常的大小堆的逻辑与大于小于相反,less排大堆,great排小堆。

这里也可转化成topK问题,建立一个大小为k的小堆,大堆每次插入时与小堆的堆顶比较,如果比小堆的堆顶大,就插入(如果满了就替换堆顶),然后调整。最后取出来的小堆的逆序就是topK。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38047.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费Typora1.8.6安装教程

&#x1f31f; Typora - 极简主义的 Markdown 编辑器免费指南 &#x1f31f; &#x1f4cc; 什么是 Typora&#xff1f; Typora 是一款广受好评的 **所见即所得** 的 Markdown 编辑器&#xff0c;以极致简洁的界面和流畅的写作体验闻名。它让 Markdown 写作变得像使用 Word 一…

元音辅音及其字母组合发音

文章目录 单元音长元音/ɑː//ɔ://u://i://ɜː/// 短元音/ʌ//ɒ//ʊ//ɪ//ə//e/ 双元音/eɪ//aɪ//ɔɪ//ɪə//eə//ʊə//əʊ//aʊ/ 辅音3个鼻辅音m n ŋ 5个独立浊辅音w j r l h 20个清浊相对的辅音s zʃ ʒf vθ p bt dk gts dztʃ dʒtr dr 以下是列举的部分字母组合…

基于FPGA频率、幅度、相位可调的任意函数发生器(DDS)实现

基于FPGA实现频率、幅度、相位可调的DDS 1 摘要 直接数字合成器( DDS ) 是一种通过生成数字形式的时变信号并进行数模转换来产生模拟波形(通常为正弦波)的方法,它通过数字方式直接合成信号,而不是通过模拟信号生成技术。DDS主要被应用于信号生成、通信系统中的本振、函…

C++调用ffmpeg解复用、解码案例

框架 一个封装文件&#xff08;mp4&#xff09;如何播放&#xff1f;大体流程如下&#xff1a; 案例 本案例实现在windows环境下&#xff0c;调用ffmpeg4.4.5动态库实现上述从解封装、视频解码、音频解码的全部过程&#xff0c;案例测试通过。由于ffmpeg接口功能网上资料较多&a…

Linux(进程)

一.冯诺依曼体系结构 输入设备&#xff1a;键盘&#xff0c;鼠标&#xff0c;话筒&#xff0c;摄像头...网卡&#xff0c;磁盘 输出设备&#xff1a;显示器&#xff0c;磁盘&#xff0c;网卡&#xff0c;打印机 外设&#xff1a;输入设备输出设备 cpu&#xff08;中央处理器&am…

[极客大挑战 2019]BabySQL—3.20BUUCTF练习day4(3)

[极客大挑战 2019]BabySQL-3.20BUUCTF练习day4(3) 做题过程 打开是以下页面&#xff08;前几天有它的第一版和第二版出现&#xff09;输入1’ 回显以下内容&#xff08;还是字符型以单引号闭合&#xff0c;因为有报错信息回显&#xff09; 输入1 order by 4%23回显成这个 被过…

[Effective C++]条款20:宁以 pass-by-reference-to-const替换 pass-by-value

. 在C中&#xff0c;函数参数与返回值的数据传递的方式&#xff0c;对程序的性能和正确性有着重要影响。C默认使用pass-by-value&#xff08;传值&#xff09;的方式传递参数。但这种方式在某些情况下会导致性能问题和对象切割问题。 C推荐使用pass-by-reference-to-const&…

文字变央视级语音转换工具

大家在制作短视频、广告宣传、有声读物、自媒体配音、学习辅助等场景的时候&#xff0c;经常会需要用到配音来增强视频的表现力和吸引力。然而&#xff0c;市面上的一些配音软件往往需要收费&#xff0c;这对于很多初学者或者预算有限的朋友来说&#xff0c;无疑增加了一定的负…

邂逅书香:在诗韵与青春中找寻心灵归处

在信息如洪流般奔涌的当下&#xff0c;我们的灵魂时常在喧嚣中漂泊&#xff0c;渴望一处宁静港湾。而书籍&#xff0c;一直以来都是人类最忠诚的精神伴侣。今天&#xff0c;要为诗歌爱好者和青春文学迷们带来两份特别的礼物——《韵之队诗集》与《青春与爱共舞》&#xff0c;它…

国科大——计网(0812)——实验作业

**前沿&#xff1a;**此博客记录了24—25年度秋季学期计算机网络&#xff08;0812&#xff09;课程的实验作业&#xff0c;所提供的材料仅供参考。 0 实验题目 本次实验总共提供了四个可选的题目&#xff0c;即BGP分析实验&#xff0c;BGP 前缀劫持攻击及检测实验&#xff0c…

新能源汽车高压液体加热器总成技术解析及未来发展趋势

引言 新能源汽车的快速发展对热管理系统提出了更高要求&#xff0c;高压液体加热器作为核心组件&#xff0c;直接影响车辆低温性能、电池寿命及用户体验。本文以实际产品为例&#xff0c;结合行业数据与技术趋势&#xff0c;深度解析高压液体加热器的技术原理、市场现状及未来…

蓝桥杯 数字接龙

问题描述 小蓝最近迷上了一款名为《数字接龙》的迷宫游戏。 游戏在一个大小为 N N 的格子棋盘上展开&#xff0c;其中每一个格子处都有一个 0 到 K-1 之间的整数。 游戏规则如下&#xff1a; 从左上角 (0, 0) 出发&#xff0c;目标是到达右下角 (N-1, N-1)。 每一步可以选…

SysVinit和Systemd的系统运行级别

Linux运行级别 SysVinit系统(init守护进程)Linux系统运行级别SysVinit系统(init守护进程)查看Linux运行级别SysVinit系统(init守护进程)修改运行级别&#xff1a; Systemd守护进程Linux系统运行级别systemd查看运行级别Systemd查看系统当前运行级别 systemd修改运行级别multi-u…

SAP SD学习笔记33 - 预詑品(寄售物料),预詑品引渡(KB),预詑品出库(KE)

上一章讲了Service品目。 SAP SD学习笔记32 - Service品目(服务产品&#xff09;-CSDN博客 本章继续讲SAP SD的知识 - 预詑品(寄售物料)。 目录 1&#xff0c;预詑品概要 1-1&#xff0c;预詑品(寄售物料)的概念 1-2&#xff0c;预詑品的4种业务 1-3&#xff0c;受托品与…

DeiT:数据高效的图像Transformer及其工作原理详解

DeiT&#xff1a;数据高效的图像Transformer及其工作原理详解 随着Transformer架构在自然语言处理&#xff08;NLP&#xff09;领域的巨大成功&#xff0c;研究者们开始探索其在计算机视觉领域的应用。Vision Transformer&#xff08;ViT&#xff09;是最早将Transformer直接应…

【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的异常处理:全局异常与自定义异常

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、开篇整…

【Mybatis-plus】在mybatis-plus中 if test标签如何判断 list不为空

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

Lineageos 22.1(Android 15)制定应用强制横屏

一、前言 有时候需要系统的某个应用强制衡平显示&#xff0c;不管他是如何配置的。我们只需要简单的拿到top的Task下面的ActivityRecord&#xff0c;并判断包名来强制实现。 二、调整wms com.android.server.wm.DisplayRotation /*** Given an orientation constant, return…

HTML网页代码预览器

HTML网页代码预览器 可以用于学习和实验HTML和CSS&#xff0c;比较方便。源码参考自网络。 功能 实时预览&#xff1a;当你在左侧的“代码编辑器”中输入代码时&#xff0c;右侧的“预览窗口”会实时显示你的网页效果&#xff08;注意&#xff0c;不能体现嵌入的JavaScript运…

Arm Linux ceres库编译

由于工作需要&#xff0c;需在国产化系统上编译ceres库&#xff0c;手上有一块树莓派&#xff0c;就在树莓派上面进行测试编译ceres库&#xff0c;总体来说比较顺利。只出现了一点小问题 参考链接&#xff1a; Ceres中文教程-安装 按照上面Linux编译过程 目录 1、在线安装依赖…