【C++進階】---- map和set的使用

1.序列式容器和關聯式容器

前?我們已經接觸過STL中的部分容器如:string、vector、list、deque、array、forward_list等,這些容器統稱為序列式容器,因為邏輯結構為線性序列的數據結構,兩個位置存儲的值之間?般沒有緊密的關聯關系,?如交換?下,他依舊是序列式容器。順序容器中的元素是按他們在容器中的存儲位置來順序保存和訪問的。
關聯式容器也是?來存儲數據的,與序列式容器不同的是,關聯式容器邏輯結構通常是?線性結構,兩個位置有緊密的關聯關系,交換?下,他的存儲結構就被破壞了。順序容器中的元素是按關鍵字來保存和訪問的。關聯式容器有map/set系列unordered_map/unordered_set系列。
本章節講解的map和set底層是紅?樹,紅?樹是?顆平衡?叉搜索樹。set是key搜索場景的結構,map是key/value搜索場景的結構。

2.set系列的使用

2.1set類的介紹

? set的聲明如下,T就是set底層關鍵字的類型

? set默認要求T?持?于?較,如果不?持或者想按??的需求?可以??實現仿函數傳給第?個模 版參數

? set底層存儲數據的內存是從空間配置器申請的,如果需要可以??實現內存池,傳給第三個參 數。

? ?般情況下,我們都不需要傳后兩個模版參數。

? set底層是?紅?樹實現,增刪查效率是,迭代器遍歷是?的搜索樹的中序,所以是有序 的。 O(logN)

? 前?部分我們已經學習了vector/list等容器的使?,STL容器接?設計,?度相似,所以這?我們 就不再?個接??個接?的介紹,?是直接帶著?家看?檔,挑?較重要的接?進?介紹。

template < class T, // set::key_type/value_typeclass Compare = less<T>, // set::key_compare/value_compareclass Alloc = allocator<T> // set::allocator_type> class set;

2.2set的構造和迭代器

set的構造我們關注以下?個接?即可。?set?持正向和反向迭代遍歷,遍歷默認按升序順序,因為底層是?叉搜索樹,迭代器遍歷?的中序;?持迭代器就意味著?持范圍for,set的iterator和const_iterator都不?持迭代器修改數據,修改 關鍵字數據,破壞了底層搜索樹的結構。

// 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& = allocator_type());// copy (3) 拷?構造 
set (const set& x);// initializer list (5) initializer 列表構造 
set (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();
#include<iostream>
#include<set>
#include<vector>
using namespace std;int main()
{// 1.無參構造set<int> s1;// 2.迭代器區間構造vector<int> v1 = { 1,2,2,3,4,5 };set<int> s2(v1.begin(), v1.end());// 3.拷貝構造set<int> s3(s2);// 4.鏈表構造set<int> s4({ 1,2,3,4,5,1,2 });return 0;
}

2.3set的增刪改

set的增刪查關注以下?個接?即可:

Member types
key_type -> The first template parameter (T)
value_type -> The first template parameter (T)// 單個數據插?,如果已經存在則插?失敗 
pair<iterator,bool> insert (const value_type& val);// 列表插?,已經在容器中存在的值不會插? 
void insert (initializer_list<value_type> il);// 迭代器區間插?,已經在容器中存在的值不會插? 
template <class InputIterator>
void insert (InputIterator first, InputIterator last);// 查找val,返回val所在的迭代器,沒有找到返回end() 
iterator find (const value_type& val);// 查找val,返回Val的個數 
size_type count (const value_type& val) const;// 刪除?個迭代器位置的值 
iterator erase (const_iterator position);// 刪除val,val不存在返回0,存在返回1 
size_type erase (const value_type& val);// 刪除?段迭代器區間的值 
iterator erase (const_iterator first, const_iterator last);// 返回?于等val位置的迭代器 
iterator lower_bound (const value_type& val) const;// 返回?于val位置的迭代器 
iterator upper_bound (const value_type& val) const;

2.4insert和迭代器遍歷使用案例

#include<iostream>
#include<set>
using namespace std;int main()
{// 去重+升序排序set<int> s1;// 去重+降序排序,給一個大于的仿函數//set<int,greater<int>> s1;s1.insert(1);s1.insert(1);s1.insert(2);s1.insert(3);//set<int>::iterator it1 = s1.begin();auto it1 = s1.begin();while (it1 != s1.end()){// error C3892: “it”: 不能給常量賦值 //*it1 = 1;cout << *it1 << " ";it1++;}cout << endl;// 插??段initializer_list列表值,已經存在的值插?失敗s1.insert({ 1,2,3,4 });for (auto e : s1){cout << e << " ";}cout << endl;set<string> strset = { "sort","insert","add" };// 遍歷string比較ascll碼大小順序遍歷的for (auto e : strset){cout << e << " ";}cout << endl;return 0;
}

2.5find和erase使用案例

#include<iostream>
#include<set>
using namespace std;int main()
{set<int> s1 = { 4,2,7,2,8,5,9 };for (auto e : s1){cout << e << " ";}cout << endl;// 刪除最小值s1.erase(s1.begin());for (auto e : s1){cout << e << " ";}cout << endl;// 直接刪除xint x;cin >> x;int num = s1.erase(x);if (num == 0){cout << x << "不存在!" << endl;}for (auto e : s1){cout << e << " ";}cout << endl;// 直接查找再利用迭代器刪除xcin >> x;auto pos = s1.find(x);if (pos != s1.end()){s1.erase(pos);}else{cout << x << "不存在!" << endl;}for (auto e : s1){cout << e << " ";}cout << endl;// 算法庫的查找O(N)auto pos1 = find(s1.begin(), s1.end(), x);// set自身實現的查找O(logN)auto pos2 = s1.find(x);// 利用count間接實現快速查找cin >> x;if (s1.count(x)){cout << x << "在!" << endl;}else{cout << x << "不在!" << endl;}return 0;
}

2.6multiset和set的差異

multiset和set的使?基本完全類似,主要區別點在于multiset?持值冗余,那么 insert/find/count/erase都圍繞著?持值冗余有所差異,具體參看下?的樣例代碼理解。

find:

#include<iostream>
#include<set>
using namespace std;int main()
{// 相?set不同的是,multiset是排序,但是不去重 multiset<int> s = { 4,2,7,2,4,8,4,5,4,9 };for (auto e : s){cout << e << " ";}cout << endl;// 相?set不同的是,x可能會存在多個,find查找中序的第?個 int x;cin >> x;auto pos = s.find(x);while (pos != s.end() && *pos == x){cout << *pos << " ";pos++;}cout << endl;// 相?set不同的是,count會返回x的實際個數 cout << s.count(x) << endl;// 相?set不同的是,erase給值時會刪除所有的xs.erase(x);for (auto e : s){cout << e << " ";}cout << endl;return 0;
}

3.map系列的使用

3.1map類型介紹

map的聲明如下,Key就是map底層關鍵字的類型,T是map底層value的類型,set默認要求Key?持 ?于?較,如果不?持或者需要的話可以??實現仿函數傳給第?個模版參數,map底層存儲數據的 內存是從空間配置器申請的。?般情況下,我們都不需要傳后兩個模版參數。map底層是?紅?樹實 現,增刪查改效率是 O(logN) ,迭代器遍歷是?的中序,所以是按key有序順序遍歷的。
template < class Key, // map::key_type key類型class T, // map::mapped_type value類型class Compare = less<Key>, // map::key_compare 數據比較class Alloc = allocator<pair<const Key,T> > //map::allocator_type 空間配置器> class map;

3.2pair類型介紹

map底層的紅?樹節點中的數據,使?pair<Key, T>存儲鍵值對數據。
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) );
}

3.3map的構造

map的構造我們關注以下?個接?即可。
map的?持正向和反向迭代遍歷,遍歷默認按key的升序順序,因為底層是?叉搜索樹,迭代器遍歷? 的中序;?持迭代器就意味著?持范圍for,map?持修改value數據,不?持修改key數據,修改關鍵 字數據,破壞了底層搜索樹的結構。
// 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();
#include<iostream>
#include<map>
using namespace std;int main()
{// 無參默認構造map<int, int> m1;// 傳參構造pair<string, int> p1 = { "英語",90 };pair<string, int> p2 = { "數學",95 };pair<string, int> p3 = { "語文",80 };map<string, int> m2 = { p1,p2,p3 };// 匿名對象初始化map<string, string> m3 = { pair<string, string>("insert", "插入") };// make_pair可自動推導模板參數類型,也可指定類型,make_pair<string,string>map<string, string> m4 = { make_pair("string","字符串") };// initializer_list構造map<string, string> m5 = { {"left", "左邊"}, {"right", "右邊"},
{"insert", "插?"},{ "string", "字符串" } };// 迭代器區間初始化map<string, string> m6(m5.begin(), m5.end());// 拷貝構造map<string, string> m7(m6);return 0;
}

3.4map的增刪查

map的增刪查關注以下?個接?即可:
map增接?,插?的pair鍵值對數據,跟set所有不同,但是查和刪的接?只?關鍵字key跟set是完全 類似的,不過find返回iterator,不僅僅可以確認key在不在,還找到key映射的value,同時通過迭代 還可以修改value
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);

3.5map的數據修改

前?我提到map?持修改mapped_type 數據,不?持修改key數據,修改關鍵字數據,破壞了底層搜 索樹的結構。
map第?個?持修改的?式時通過迭代器,迭代器遍歷時或者find返回key所在的iterator修改,map 還有?個?常重要的修改接?operator[],但是operator[]不僅僅?持修改,還?持插?數據和查找數據,所以他是?個多功能復合接?。
需要注意從內部實現?度,map這?把我們傳統說的value值,給的是T類型,typedef為
mapped_type。?value_type是紅?樹結點中存儲的pair鍵值對值。?常使?我們還是習慣將這?的 T映射值叫做value。

operator[]內部調用insert,insert的返回值是pair<iterator,bool>,如果插入成功,返回的pair的first是新插入key所在節點的迭代器,second是true。如果插入失敗,返回的pair的first是已經存在的key所在節點的迭代器,second是false。mapped_type()是value的默認構造,對于自定義成員會調用其默認構造,對于內置類型,如int,會初始化成0,double會初始化成0.0

插入成功的時候,operator[]具備了插入+修改的功能。

插入失敗的時候,operator[]具備了查找+修改的功能。

Member types
key_type -> The first template parameter (Key)
mapped_type -> The second template parameter (T)
value_type -> pair<const key_type,mapped_type>// 查找k,返回k所在的迭代器,沒有找到返回end(),如果找到了通過iterator可以修改key對應的
mapped_type值
iterator find (const key_type& k);// ?檔中對insert返回值的說明
// The single element versions (1) return a pair, with its member pair::first
set to an iterator pointing to either the newly inserted element or to the
element with an equivalent key in the map. The pair::second element in the pair
is set to true if a new element was inserted or false if an equivalent key
already existed.// insert插??個pair<key, T>對象
// 1、如果key已經在map中,插?失敗,則返回?個pair<iterator,bool>對象,返回pair對象
first是key所在結點的迭代器,second是false
// 2、如果key不在在map中,插?成功,則返回?個pair<iterator,bool>對象,返回pair對象
first是新插?key所在結點的迭代器,second是true
// 也就是說?論插?成功還是失敗,返回pair<iterator,bool>對象的first都會指向key所在的迭
代器
// 那么也就意味著insert插?失敗時充當了查找的功能,正是因為這?點,insert可以?來實現
operator[]
// 需要注意的是這?有兩個pair,不要混淆了,?個是map底層紅?樹節點中存的pair<key, T>,另
?個是insert返回值pair<iterator,bool>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;
}

3.6構造遍歷及增刪查使用樣例

#include<iostream>
#include<map>
using namespace std;int main()
{// initializer_list構造及迭代遍歷map<string, string> dict = { {"left", "左邊"}, {"right", "右邊"},
{"insert", "插入"},{ "string", "字符串" } };auto it = dict.begin();while (it != dict.end()){//cout << (*it).first <<":"<<(*it).second << endl;// map的迭代基本都使?operator->,這?省略了?個->// 第一個->是迭代器運算符重載,返回pair*,第二個箭頭是結構指針解引?取pair數據//cout << it.operator->()->first << ":" << it.operator->()-> second << endl;cout << it->first << ":" << it->second << endl;it++;}cout << endl;// insert插?pair對象的4種?式,對?之下,最后?種最?便pair<string, string> kv1("first", "第一個");dict.insert(kv1);dict.insert(pair<string, string>("second", "第二個"));dict.insert(make_pair("sort", "排序"));dict.insert({ "auto","自動的" });// map不允許鍵值冗余,已經存在的key會插入失敗dict.insert({ "left", "左邊,剩余" });for (const auto& e : dict){cout << e.first << ":" << e.second << endl;}cout << endl;// 查找string str;while (cin >> str){auto ret = dict.find(str);if (ret != dict.end()){cout << "->" << ret->second << endl;}else{cout << "查無此單詞" << endl;}}// erase等接?跟set完全類似return 0;
}

3.7map的迭代器和[]功能樣例

#include<iostream>
#include<map>
using namespace std;int main()
{// 1.利用find和iterator修改功能,統計水果出現次數string arr[] = { "蘋果", "西瓜", "蘋果", "西瓜", "蘋果", "蘋果", "西瓜",
"蘋果", "香蕉", "蘋果", "香蕉" };map<string, int> countMap;for (const auto& str : arr){// 先查找?果在不在map中// 1、不在,說明?果第?次出現,則插?{?果, 1}// 2、在,則查找到的節點中?果對應的次數++auto ret = countMap.find(str);if (ret == countMap.end()){countMap.insert({str,1});}else{ret->second++;}}for (const auto& e : countMap){cout << e.first << ":" << e.second << endl;}cout << endl;// 2.利?[]插?+修改功能,巧妙實現統計?果出現的次數map<string, int> countMap2;for (const auto& str : arr){// []先查找?果在不在map中// 1、不在,說明?果第?次出現,則插?{?果, 0},同時返回次數的引?,++?下就變成1次了// 2、在,則返回?果對應的次數++// 不在的時候[]具有查找+修改功能// 在的時候[]具有插入+修改功能countMap2[str]++;}for (const auto& e : countMap2){cout << e.first << ":" << e.second << endl;}// 3.[]的功能map<string, string> dict;dict.insert(make_pair("sort", "排序"));// key不存在->插? {"insert", string()}dict["insert"];// 插?+修改dict["left"] = "左邊";// 修改dict["left"] = "左邊、剩余";// key存在->查找cout << dict["left"] << endl;return 0;
}

3.8multimap和map的差異

multimap和map的使?基本完全類似,主要區別點在于multimap?持關鍵值key冗余,那么
insert/find/count/erase都圍繞著?持關鍵值key冗余有所差異,這?跟set和multiset完全?樣,?如 find時,有多個key,返回中序第?個。其次就是multimap不?持[],因為?持key冗余,[]就只能? 持插?了,不能?持修改。

4.兩道相關題

4.1隨機鏈表的復制

https://leetcode.cn/problems/copy-list-with-random-pointer/description/

// 1.隨機鏈表的復制
/*
// Definition for a Node.
class Node {
public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = NULL;random = NULL;}
};
*/// 1.
// 利用原鏈表的節點做key,新鏈表對應的節點做value
// 后續新鏈表的random就是nodeMap[cur->random]
// 通過原鏈表的random節點,找到新鏈表的random節點
class Solution {
public:Node* copyRandomList(Node* head) {map<Node*, Node*> nodeMap;Node* copyhead = nullptr, * copytail = nullptr;Node* cur = head;while (cur){if (copytail == nullptr){// 空鏈表copyhead = copytail = new Node(cur->val);}else{//尾插copytail->next = new Node(cur->val);copytail = copytail->next;}// 原鏈表節點做key,新鏈表節點做valuenodeMap[cur] = copytail;cur = cur->next;}cur = head;Node* copyCur = copyhead;while (cur){if (cur->random == nullptr){copyCur->random = nullptr;}else{copyCur->random = nodeMap[cur->random];}cur = cur->next;copyCur = copyCur->next;}return copyhead;}
};// 2.在原節點后面尾接新的相同的節點,然后copy->random=cur->random->next,然后在從原鏈表上分離
class Solution {
public:Node* copyRandomList(Node* head) {if (head == nullptr)return nullptr;Node* cur = head;while (cur){Node* newNode = new Node(cur->val);newNode->next = cur->next;cur->next = newNode;cur = cur->next->next;}cur = head;Node* copyCur = cur->next;while (cur){if (cur->random == nullptr){copyCur->random = nullptr;}else{copyCur->random = cur->random->next;}cur = cur->next->next;if (cur != nullptr)copyCur = copyCur->next->next;}Node* copyhead = nullptr, * copytail = nullptr;cur = head;while (cur){Node* nextNode = cur->next->next;if (copyhead == nullptr){copyhead = copytail = cur->next;}else{copytail->next = cur->next;copytail = copytail->next;}cur->next = nextNode;cur = nextNode;}return copyhead;}
};

4.2前k個高頻單詞

https://leetcode.cn/problems/top-k-frequent-words/submissions/661053571/

class Solution {
public:// 將words里的數據放入map中統計個數順便排序// 再把map里的數據轉入vectror中讓sort排序,// 因為sort只支持隨機迭代器容器的排序// 在寫個仿函數指定比較規則struct kvCompare{bool operator()(const pair<string, int>& p1, const pair<string, int>& p2) const{return p1.second > p2.second ||(p1.second == p2.second && p1.first < p2.first);}};vector<string> topKFrequent(vector<string>& words, int k) {map<string, int> countMap;for (const auto& e : words){countMap[e]++;}vector<pair<string, int>> v(countMap.begin(), countMap.end());sort(v.begin(), v.end(), kvCompare());//stable_sort(v.begin(), v.end(), kvCompare());// stable_sort是穩定排序,不會破壞順序,只寫return p1.second > p2.second即可vector<string> ret;for (int i = 0; i < k; i++){ret.push_back(v[i].first);}return ret;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98571.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98571.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98571.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

430章:Python Web爬蟲入門:使用Requests和BeautifulSoup

在軟件交付日益高頻、用戶需求快速迭代的今天&#xff0c;版本發布流程的規范性直接決定了團隊的交付效率、產品質量和用戶滿意度。然而&#xff0c;許多團隊仍面臨以下痛點&#xff1a;發布混亂&#xff1a;分支管理隨意&#xff0c;代碼沖突頻發&#xff1b;質量失控&#xf…

代碼隨想錄第七天|● 454.四數相加II ● 383. 贖金信 ● 15. 三數之和 18.四數之和

本文所有題目鏈接/文章講解/視頻講解&#xff1a;https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II.html 454.四數相加II 有四個數組&#xff0c;如果要遍歷則時間復雜度太大 可以選擇分組&#xff0c;a和b一組&#xff0c;c和d一組 這樣就可以等同于…

Vue3源碼reactivity響應式篇之computed計算屬性

概述 vue3中&#xff0c;computed函數用于表示計算屬性&#xff0c;有惰性求值、響應式追蹤依賴的特點。本文將介紹computed的實現原理以及其機制細節。 源碼解析 computed計算屬性和computed方法、ComputedRefImpl類以及refreshComputed方法有關。 computed方法 computed暴露給…

[嵌入式embed]Keil5燒錄后STM32不自動運行,復位才能運行

[嵌入式embed]Keil5燒錄后STM32不自動運行,復位才能運行Keil5-驗證“Reset and Run”功能是否生效參考文章Keil5-驗證“Reset and Run”功能是否生效 參考文章 Keil5燒錄后STM32不自動運行&#xff1f;必須復位才能啟動的終極解決方案

阿里云Qwen3系列模型部署微調評測

與阿里云一起輕松實現數智化讓算力成為公共服務&#xff1a;用大規模的通用計算&#xff0c;幫助客戶做從前不能做的事情&#xff0c;做從前做不到的規模。讓數據成為生產資料&#xff1a;用數據的實時在線&#xff0c;幫助客戶以數據為中心改變生產生活方式創造新的價值。模型…

北京魯成偉業 | 三屏加固筆記本電腦C156F3

在工業控制、應急指揮、測控及無人機作業等對設備穩定性與環境適應性要求較高的領域&#xff0c;一款性能均衡且堅固耐用的計算機往往能為工作效率提供有力支撐。三屏加固筆記本電腦C156F3便是針對這類需求設計的設備&#xff0c;憑借多方面的特性&#xff0c;可滿足不同場景下…

七彩氛圍燈芯片EH3A01RGB驅動芯片定時開關IC方案

?在現代智能家居和個性化照明領域&#xff0c;EH3A01-442A-A24F小夜燈定時芯片憑借其多功能、低功耗和靈活配置的特點&#xff0c;成為LED氛圍燈、小夜燈及便攜式照明方案的理想選擇。本文將深入解析該芯片的核心功能、電氣特性及應用場景&#xff0c;幫助開發者與用戶全面掌握…

Spring Boot 項目新增 Module 完整指南

1. 模塊化開發的重要性 在軟件開發中&#xff0c;隨著項目規模的不斷擴大&#xff0c;??模塊化設計??已成為提高代碼可維護性和可復用性的關鍵實踐。通過將大型項目拆分為多個獨立模塊&#xff0c;開發團隊可以??并行開發??不同功能組件&#xff0c;降低代碼耦合度&…

Git cherry-pick 與分支重置技術實現代碼健全性保障下的提交記錄精簡

代碼健全性保障&#xff1a;上市審查中的 Git 提交記錄整理方案&#xff08;核心功能提交篩選流程&#xff09; 一、背景與目的 我司正處于上市籌備階段&#xff0c;券商需對核心系統進行 Git 代碼審查&#xff0c;并基于提交記錄生成測試報告。由于原始提交記錄包含大量細節性…

前后端聯調時出現的一些問題記錄

服務器的ip沒有設置成所有ip都能訪問的&#xff0c;或防火墻沒開跨域問題&#xff08;剛開始異源&#xff0c;有這個問題&#xff0c;主要是前端做一下配置代理&#xff0c;后端也可以配置跨域資源共享&#xff08;CORS&#xff09;&#xff09;Configuration public class Cor…

數字圖像處理-設計生成一個半球

1 實驗題目設計生成一個半球&#xff08;matlab&#xff09;。2 程序源代碼%Hemisphere clear,clc,close all %Sphere radius R1; %Set grid number n30; theta (-n:2:n)/n*pi; phi ([0,0:2:n])/n*pi/2; cosphi cos(phi); cosphi(1) 0; cosphi(end) 0; sintheta sin(thet…

mac M1上安裝windows虛擬機報錯

Parallels版本是18.0.02 mac&#xff1a;arm系統15.6.1 自動獲取windows11下載&#xff0c;安裝的時候報錯&#xff0c;藍屏&#xff0c;是因為安裝的版本不對&#xff0c;猜測原因應該是18.0.02不支持最新版的windows11&#xff0c;需要更新最新版的Parallels。 解決方案&am…

基于R語言機器學習方法在生態經濟學領域中的實踐技術應用

近年來&#xff0c;人工智能領域已經取得突破性進展&#xff0c;對經濟社會各個領域都產生了重大影響&#xff0c;結合了統計學、數據科學和計算機科學的機器學習是人工智能的主流方向之一&#xff0c;目前也在飛快的融入計量經濟學研究。表面上機器學習通常使用大數據&#xf…

第01章 初識MySQL與mysql8.0的安裝

初識 MySQL 文章目錄初識 MySQL引言一、數據庫基礎1.1 什么是數據庫1.2 表1.3 數據類型1.4 主鍵二、數據庫技術構成2.1 數據庫系統2.2 SQL 語言2.2.1 數據定義語言&#xff08;DDL&#xff09;2.2.2 數據操作語言&#xff08;DML&#xff09;2.2.3 數據查詢語言&#xff08;DQL…

【數據結構基礎習題】-1- 數據結構基本操作

一、順序表和鏈表習題 1. 順序表就地逆置#include <stdio.h> // 定義順序表結構 #define MAXSIZE 100 typedef struct {int data[MAXSIZE];int length; } SqList; // 就地逆置順序表 void reverseList(SqList *L) {int i, temp;for (i 0; i < L->length / 2; i) {…

【Java實戰?】從0到1:Spring Boot Web開發與接口設計實戰

目錄一、Spring Boot Web 基礎配置1.1 Web 起步依賴&#xff08;spring-boot-starter-web 導入與核心組件&#xff09;1.2 內置服務器配置&#xff08;Tomcat 端口、線程池、連接超時設置&#xff09;1.3 靜態資源訪問&#xff08;靜態資源存放路徑、自定義資源映射&#xff09…

房屋安全鑒定機構評價

房屋安全鑒定機構評價&#xff1a;如何選擇專業可靠的檢測服務在建筑行業快速發展的今天&#xff0c;房屋安全鑒定已成為保障建筑安全、預防事故的重要環節。面對市場上眾多的房屋安全鑒定機構&#xff0c;如何科學評價并選擇一家專業可靠的服務提供方&#xff0c;是許多業主、…

【算法專題訓練】19、哈希表

1、哈希表基礎知識 以鍵值對的方式進行數據存儲優點&#xff1a;哈希表數據結構在插入、刪除或查找一個元素時&#xff0c;都只需要O(1)的時間 哈希表設計三要點&#xff1a; 為了快速確定一個元素在哈希表中的位置&#xff0c;可以使用一個數組&#xff0c;元素的位置為他的…

某光伏電力監控系統網絡安全監測項目:智能組網技術優化方案實踐

背景與挑戰隨著光伏電力行業的快速發展&#xff0c;光伏電站的規模和分布范圍日益擴大。電力監控系統作為光伏電站的核心平臺&#xff0c;其網絡安全直接關系到電力生產的穩定性與可靠性。然而&#xff0c;光伏場站通常分布在偏遠地區&#xff0c;網絡環境復雜&#xff0c;傳統…

GEE訓練教程:基于Landsat 8衛星影像識別并提取指定區域內無云覆蓋的區域多邊形,最終導出為矢量文件

簡介 本文使用Google Earth Engine平臺,通過Landsat 8衛星影像識別并提取指定區域內無云覆蓋的區域多邊形,最終導出為矢量文件。主要步驟包括:定義研究區域、創建云檢測算法、篩選高質量影像、將無云區域轉換為矢量多邊形,并進行可視化檢查和數據導出。 使用Google Earth…