【C++/STL深度剖析】priority_queue 最全解析(什么是priority_queue? priority_queue的常用接口有哪些?)

目錄

一、前言

二、如何區分【優先級隊列】與【隊列】?

三、priority_queue的介紹?

四、priority_queue 的構造?

五、priority_queue 的常用接口?

💧push

💧pop?

💧size??

💧top??

💧empty???

💧swap? ??

六、priority_queue 的模擬實現?

🥝 堆的向上調整算法

🥝 堆的向下調整算法

🥝 priority_queue 的實現

七、priority_ququq 中的仿函數?

八、priority_queue 的常考面試?

九、總結?

十、共勉?


一、前言

? ? ? ? 優先級隊列 priority_queue容器適配器中的一種,常用來進行對數據進行優先級處理,比如優先級高的值在前面,這其實就是數據結構中的 堆,它倆本質上是一樣東西,底層都是以數組存儲的完全二叉樹,不過優先級隊列 priority_queue 中加入了 泛型編程 的思想,并且屬于 STL 中的一部分。本就就來詳細的講解一下 priority_queue 是如何使用的!!

?二、如何區分【優先級隊列】與【隊列】?

首先要注意的就是別與 隊列(queue)搞混了隊列是一種先進先出(First in First out,FIFO)的數據類型。每次元素的入隊都只能添加到隊列尾部,出隊時從隊列頭部開始出

優先級隊列(priority_queue)其實,不滿足先進先出的條件,更像是數據類型中的“堆”優先級隊列每次出隊的元素是隊列中優先級最高的那個元素,而不是隊首的元素。這個優先級可以通過元素的大小等進行定義。比如定義元素越大優先級越高,那么每次出隊,都是將當前隊列中最大的那個元素出隊。

三、priority_queue的介紹?

? ? ? ? priority_queue是C++標準庫中的一個容器適配器(container adapter),用于實現優先隊列(priority queue)的數據結構。優先隊列是一種特殊的隊列,其中的元素按照一定的優先級進行排序,每次取出的元素都是優先級最高的。它的底層實現通常使用堆(heap)數據結構。

  • 在C++中,priority_queue模板類定義在<queue>頭文件中,可以通過指定元素類型和比較函數來創建不同類型的優先隊列。比較函數用于確定元素的優先級,可以是函數指針、函數對象或Lambda表達式。
  • ?priority_queue被實現為容器適配器,容器適配器即將特定容器類封裝作為其底層容器類。元素從特定容器的”尾部“彈出,其稱為優先級隊列的頂部

?需要注意的是,默認情況下,priority_queue使用std::less作為比較函數,即元素的優先級按照從大到小的順序排列。如果需要按照從小到大的順序排列,可以使用std::greater作為比較函數。?

四、priority_queue 的構造?

? ? ? ? 優先級隊列 默認使用 vector 作為底層存儲數據的容器,在 vector 上又使用了 堆算法 將 vector 中的元素構造成堆的結構,因此 priority_queue 就是 ---- 堆,所以在需要用到 堆 的地方,都可以考慮使用 priority_queue

注意:默認情況下 priority_queue 是 大堆

?優先級隊列的構造方式有兩種:直接構造一個空對象?和?通過迭代器區間進行構造

?(1)直接構造一個空對象

#include <iostream>
#include <vector>
#include <queue>	//注意:優先級隊列包含在 queue 的頭文件中using namespace std;int main()
{priority_queue<int> pq;	//直接構造一個空對象,默認為大堆cout << typeid(pq).name() << endl;	//查看類型return 0;
}

注意:?默認比較方式為?less,最終為 優先級高的值排在上面(大堆


(2)通過迭代器區間構造對象?

#include <iostream>
#include <vector>
#include <queue>	//注意:優先級隊列包含在 queue 的頭文件中using namespace std;int main()
{vector<char> vc = { 'a','b','c','d','e' };priority_queue<char, deque<char>, greater<char>> pq(vc.begin(), vc.end());	//現在是小堆cout << typeid(pq).name() << endl;	//查看類型cout << "==========================" << endl;while (!pq.empty()){//將小堆中的堆頂元素,依次打印cout << pq.top() << " ";pq.pop();}return 0;
}

注意:?將比較方式改為?greater?后,生成的是?小堆,并且如果想修改比較方式的話,需要指明模板參數2?底層容器,因為比較方式位于模板參數3,不能跳躍缺省(遵循缺省參數規則)?


測試數據:【27,15,19,18,28,34,65,49,25,37】?分別生成 大堆 小堆?

大堆?:

vector<int> v = { 27,15,19,18,28,34,65,49,25,37 };
priority_queue<int, vector<int>, less<int>> pq(v.begin(), v.end());
//priority_queue<int> pq(v.begin(), v.end());	//兩種寫法結果是一樣的,默認為大堆


小堆:?

vector<int> v = { 27,15,19,18,28,34,65,49,25,37 };
priority_queue<int, vector<int>, greater<int>> pq(v.begin(), v.end());	//生成小堆


五、priority_queue 的常用接口?

優先級隊列的接口也很簡單,唯一需要注意的是,每插入一個元素,都會進行排序,主要看你構建的是大堆還是小堆。

💧push

在優先級隊列的尾部插入 一個 新的元素,每次插入前調用 堆排序算法,將其重新排序在堆中的位置?

void test_priority_queue()
{priority_queue<int, vector<int>, greater<int>> pq; // 構建小堆pq.push(2);pq.push(10);pq.push(7);pq.push(3);pq.push(5);cout << pq.top() << endl;pq.push(0);cout << pq.top() << endl;
}
  • 可以看到,我們構建的是小堆,排好序以后,隊頭(堆頂)的數據就是 2 ,重新插入一個 0 以后,會重新排序,此時隊頭(堆頂)的數據就是 0?


💧pop?

?刪除位于優先級隊列頂部的元素,有效的將其大小減少 1,其實就是刪除隊頭元素

void test_priority_queue()
{priority_queue<int, vector<int>, greater<int>> pq; // 構建小堆pq.push(2);pq.push(10);pq.push(7);pq.push(3);pq.push(5);pq.push(1);cout << pq.top() << endl;pq.pop();cout << pq.top() << endl;
}


💧size??

返回優先級隊列的元素數量?

void test_priority_queue()
{priority_queue<int, vector<int>, greater<int>> pq; // 構建小堆pq.push(2);pq.push(10);pq.push(7);pq.push(3);pq.push(5);pq.push(1);cout << pq.size() << endl;}


💧top??

返回 優先級隊列中頂部元素的常量引用,頂部元素實在優先級隊列中比較高的元素?

void test_priority_queue()
{priority_queue<int, vector<int>, greater<int>> pq; // 構建小堆pq.push(2);pq.push(10);pq.push(7);pq.push(3);pq.push(5);pq.push(1);cout << pq.top() << endl;
}


💧empty???

?測試容器是否為空

優先級隊列同樣也不支持迭代器的遍歷,所以可以使用 empty 配合 toppop 來實現?

void test_priority_queue()
{priority_queue<int, vector<int>, greater<int>> pq; // 構建小堆pq.push(2);pq.push(10);pq.push(7);pq.push(3);pq.push(5);pq.push(1);while (!pq.empty()) {cout << pq.top() << " ";pq.pop();}
}


💧swap? ??

交換兩個優先級隊列的內容

void test_priority_queue()
{priority_queue<int> pq1; // 構建小堆pq1.push(2);pq1.push(1);pq1.push(7);pq1.push(3);priority_queue<int> pq2;pq2.push(5);pq2.push(1);pq2.push(2);pq1.swap(pq2);while (!pq1.empty()) {cout << pq1.top() << " ";pq1.pop();}cout << endl;while (!pq2.empty()) {cout << pq2.top() << " ";pq2.pop();}
}

?注意:交換的前提必須是 兩個隊列構建都是相同的類型的堆


六、priority_queue 的模擬實現?

我們知道「priority_ queue」 的底層就是,所以在模擬實現之前,要先實現堆的調整算法。?

🥝 堆的向上調整算法

假設我們現在已經有一個大堆, 我們需要在堆的末尾插入數據,然后對其進行調整,使其仍然保持大堆的結構。

堆的向上調整算法基本思想: (以建 大堆為例)?

  • 將要插入的數據與其父節點數據比較?
  • 若插入節點的數據大于父節點的數據,則交換位置,交換以后,插入的節點繼續進行向上調整(此時該節點叔和上面的父節點比

來看一個動圖 :?

  • (1) 首先我們在該大堆的末尾插入數據 60。?
  • (2) 我們先將 60 與其父結點 27 進行比較,發現 60 比其父結點大,則交換父子結點的數據,并繼續進行向.上調整。
  • (3) 此時將 60 與其父結點 28 進行比較,發現 60 還是比父結點大,則繼續交換父子結點的數據,并繼續進行向上調整。
  • (4) 這時再將 60 與其父結點 65 進行比較,發現 60 比其父結點小,則停止向上調整,此時該樹已經就是大堆了。

堆 的向上調整代碼:?

void AdjustUp(vector<int>& v1, int child)
{int parent = ((child - 1) >> 1); // 通過child計算parent的下標while (child > 0) //調整到根結點的位置截止{if (v1[parent] < v1[parent]){// 父節點與子節點交換swap(v1[child], v1[parent]);// 繼續向上調整child = parent;parent = ((child - 1) >> 1);}else {break;}}
}

🥝 堆的向下調整算法

以小堆為例,向下調整算法有一個前提,就是待向下調整的結點的左子樹和右子樹必須都為小堆?

?堆的向下調整算法基本思想: (以建小堆為例)

  • 從根節點開始,選出左右孩子節點中值較小的一個,讓父親與較小的孩子比較。?
  • 若父親大于此孩子那么交換,交換以后,繼續進行向下調整;若父親小于此孩子,則不交換,停止向下調整,此時該樹已經是小堆

如下圖所示:將該二叉樹從根結點開始進行向下調整。(此時根結點的左右子樹已經是小堆)

將 27 與其較小的子結點 15 進行比較,發現 25 其較小的子結點大,則交換這兩個結點的數據,并繼續進行向下調整。?

此時再將27與其較小的子結點18進行比較,發現27其較大的子結點大,則再交換這兩個結點的數據,并繼續進行向下調整。?

此時再將27與其較小的子結點25進行比較,發現27其較小的子結點大,則再交換這兩個結點的數據,并繼續進行向下調整。

此時該樹,就因該是小堆啦?

堆的向下調整代碼:?

//堆的向下調整(小堆)
void AdjustDown(vector<int>& v1, int n, int parent)
{//child記錄左右孩子中值較大的孩子的下標int child = 2 * parent + 1;//先默認其左孩子的值較小while (child < n){if (child + 1 < n && v1[child + 1] < v1[child])//右孩子存在并且右孩子比左孩子小{child++;//較小的孩子改為右孩子}if (v1[child] < v1[parent])//左右孩子中較小孩子的值比父結點還小{//將父結點與較小的子結點交換swap(v1[child], v1[parent]);//繼續向下進行調整parent = child;child = 2 * parent + 1;}else{break;}}
}

🥝 priority_queue 的實現

通過對「priority_ _queue」 的了 解其底層結構就是堆,此處只需對堆的調整算法和常用接口進行通用的封裝即可。?

namespace xas
{// 比較方式(使內部結構為大堆)template<class T>struct less{bool operator()(const T& x, const T& y) const{return x < y;}};// 比較方式(使內部結構為小堆)template<class T>struct greater{bool operator()(const T& x, const T& y) const{return x > y;}};// 優先級隊列 --- 大堆 < --- 小堆 >template<class T, class Container = vector<T>, class Compare = less<T>>class priority_queue{Compare _comFunc; // 比較方式public:// 創造空的優先級隊列priority_queue(const Compare& comFunc = Compare()):_comFunc(comFunc){}// 以迭代器區間來建堆template <class InputIterator>priority_queue(InputIterator first, InputIterator last, const Compare& comFunc = Compare()): _comFunc(comFunc){while (first != last){_con.push_back(*first);++first;}// 建堆for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i){AdjustDown(i);}}// 堆的向上調整void AdjustUp(int child){int parent = (child - 1) / 2; // 通過child計算parent的下標while (child > 0){if (_comFunc(_con[parent], _con[child])) // 通過所給比較方式確定是否需要交換結點位置{swap(_con[parent], _con[child]); // 將父結點與孩子結點交換child = parent; //繼續向上進行調整parent = (child - 1) / 2;}else{break;}}}// 插入元素到隊尾(并排序)// 在容器尾部插入元素后進行一次向上調整算法void push(const T& x){_con.push_back(x);AdjustUp(_con.size() - 1);}// 堆的向下調整void AdjustDown(int parent){size_t child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && _comFunc(_con[child], _con[child + 1])){++child;}if (_comFunc(_con[parent], _con[child])) //通過所給比較方式確定是否需要交換結點位置{swap(_con[parent], _con[child]); //將父結點與孩子結點交換parent = child; //繼續向下進行調整child = parent * 2 + 1;}else{break;}}}// 刪除隊頭元素(堆頂元素)// 將容器頭部和尾部元素交換,再將尾部元素刪除,最后從根結點開始進行一次向下調整算法void pop(){assert(!_con.empty());swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}// 訪問隊頭元素(堆頂元素)const T& top(){return _con[0];}// 獲取隊列中有效元素個數size_t size(){return _con.size();}// 判斷隊列是否為空bool empty(){return _con.empty();}private:Container _con;};// 測試函數void test_priority_queue1(){priority_queue<int> pq1; // 構建大堆pq1.push(2);pq1.push(1);pq1.push(7);pq1.push(5);pq1.push(3);pq1.push(10);pq1.push(4);while (!pq1.empty()) {cout << pq1.top() << " ";pq1.pop();}}// 測試函數void test_priority_queue2(){priority_queue<int, vector<int>, greater<int>> pq2; // 構建小堆pq2.push(2);pq2.push(1);pq2.push(7);pq2.push(5);pq2.push(3);pq2.push(10);pq2.push(4);while (!pq2.empty()) {cout << pq2.top() << " ";pq2.pop();}}
}

七、priority_ququq 中的仿函數?

? ? ? ? 在priority_queue中,仿函數用于比較元素的優先級,并根據其返回值確定它們在隊列中的位置。默認情況下,priority_queue使用std::less作為仿函數,也就是將元素按照從大到小的順序進行排序。?

你可以使用不同的仿函數來改變元素的排序方式。以下是一些常見的仿函數:?

  • std::less<T>對于基本數據類型和自定義類型,默認使用?<?運算符進行比較,按照從大到小的順序排序。
  • std::greater<T>對于基本數據類型和自定義類型,默認使用?>?運算符進行比較,按照從小到大的順序排序。

除了上述默認提供的仿函數外,你還可以自定義仿函數來實現自定義的元素比較規則。自定義仿函數需要滿足嚴格弱排序(Strict Weak Ordering)的要求,即:?

  • 比較關系必須是可傳遞的(transitive):對于任意元素a、b和c,如果a與b比較相等,b與c比較相等,則a與c比較也相等。
  • 比較關系不能是部分順序(partial order):對于任意元素a和b,它們不能同時大于、小于或等于彼此。
  • 比較關系必須是可比較的(comparable):比較關系的結果必須對所有元素定義明確的大小關系。

以下這段代碼,演示了如何自定義一個仿函數來實現元素的自定義排序方式:?

// 創建一個 身份結構體
struct Person
{string name;int age;// 構造函數Person(const string& n, int a):name(n), age(a){}
};// 自定義仿函數
struct Compare
{// 函數重載()bool operator()(const Person& p1, const Person& p2)const{//按照年齡從下到大排序return p1.age > p2.age;}
};int main()
{priority_queue<Person, vector<Person>, Compare> pq;pq.push(Person("Alice", 25));pq.push(Person("Bob", 30));pq.push(Person("Charlie", 20));while (!pq.empty()) {Person p = pq.top();pq.pop();cout << p.name << " - " << p.age << endl;}return 0;
}

輸出結果為:?

Charlie - 20
Alice - 25
Bob - 30

在上面的代碼中,我們定義了一個名為Compare的結構體,重載了函數調用運算符operator()按照Person對象的age成員進行比較。然后,我們將Compare作為優先隊列的仿函數類型,并插入3個Person對象到優先隊列中。最后,我們按照自定義的排序方式依次取出元素并輸出。?


八、priority_queue 的常考面試?

優先級隊列(堆)可以用來進行排序和解決?Top-K?問題,比如?查找第 k 個最大的值?就比較適合使用優先級隊列?

215. 數組中的第K個最大元素 - 力扣(LeetCode)?

思路:利用數組建立大堆,數組從大到小排序,刪除前k-1個元素,選出隊頭即可

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {// 將數組中的元素 放入 優先級隊列--堆priority_queue<int> p(nums.begin(),nums.end());// 將優先級隊列 中的前K-1 個元素刪除掉for(int i = 0;i< k-1;i++){p.pop();}return p.top();}
};

?九、總結?

優先隊列是一種特殊的隊列,其中存儲的元素按照一定的優先級進行排列。在priority_queue中,優先級最高的元素能夠快速被訪問和刪除。

  • 首先,我們介紹了priority_queue的概念和特點。它是基于堆(heap)這種數據結構實現的,通常使用最大堆來進行內部排序。最大堆保證了根節點的值最大,并且任意節點的值大于或等于其子節點的值。這種特性使得優先隊列能夠高效地訪問和刪除具有最高優先級的元素。
  • 接著,我們深入探討了priority_queue的使用方法。基本操作包括插入元素、刪除元素、訪問元素和檢查隊列是否為空。
  • 底層結構是priority_queue的關鍵部分,它通常使用堆來實現。在堆中,通過使用數組的索引來表示節點之間的關系,能夠快速定位和操作元素。
  • 最后,我們探討了在priority_queue中使用的仿函數。仿函數用于確定元素之間的優先級,決定元素在隊列中的位置。默認情況下,priority_queue使用std::less仿函數進行比較,對元素進行降序排列。你還可以選擇其他仿函數或自定義仿函數來實現不同的排序方式。

十、共勉?

? ? ??以下就是我對 【priority_queue優先級隊列】?的理解,如果有不懂和發現問題的小伙伴,請在評論區說出來哦,同時我還會繼續更新對?C++STL?的理解,請持續關注我哦!!!???

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

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

相關文章

YOLOv5改進 | 損失函數 | EIoU、SIoU、WIoU、DIoU、FocuSIoU等多種損失函數

秋招面試專欄推薦 &#xff1a;深度學習算法工程師面試問題總結【百面算法工程師】——點擊即可跳轉 &#x1f4a1;&#x1f4a1;&#x1f4a1;本專欄所有程序均經過測試&#xff0c;可成功執行&#x1f4a1;&#x1f4a1;&#x1f4a1; 專欄目錄&#xff1a; 《YOLOv5入門 …

Nginx-rewrite模塊詳解

文章目錄 前言一、ngx_http_rewrite_module模塊二、指令詳解1.break案例 2. if指令案例 3. return指令案例&#xff1a;return 的優先級 4. rewrite指令案例 5. set指令 總結 前言 nginx一些場景&#xff0c;我們需要使用rewrite模塊。例如域名改了&#xff0c;為了利用網站se…

什么是YUV和IPB,PTS和DTS,視頻編碼解碼過程

YUV 是一種在視頻處理和壓縮中常用的顏色空間。 它將圖像的亮度 (Y) 與色度 (U 和 V) 成分分開。 這種分離對視頻壓縮和廣播非常有益&#xff0c; 因為人眼對亮度變化比對顏色變化更敏感。 YUV 組件簡介 Y (亮度)&#xff1a;表示圖像的亮度或灰度信息。U (色度)&#xff1a;…

git - 變基、合并、重置后的回退操作

介紹 ORIG_HEAD 是 Git 中一個特殊的引用&#xff0c;用來指向某些操作&#xff08;如合并、變基、重置等&#xff09;前的狀態。它可以用來快速恢復到這些操作之前的狀態。下面是 ORIG_HEAD 的用法和一些常見的使用場景&#xff1a; 用法 1. 查看 ORIG_HEAD 使用以下命令查…

程序員需要具備的核心競爭力

隨著IT人才的飽和&#xff0c;互聯網就業形勢越嚴峻。 作為一名工程師&#xff0c;需要具備哪些基本素養與能力&#xff0c;才能夠應對這樣的就業環境&#xff1f; 按照優先級排序如下&#xff1a; 1 業務理解、需求溝通能力 業務理解與需求溝通看似是技術經理、架構師需要…

四模衛星導航模塊-高精度多模衛星定位技術

GPS02-UBX模塊是思為無線基于u-blox最新款IC M10系列研發的一款全球衛星系統定位GPS/北斗模塊。它可以支持BDS/GPS/GLONASS/Galileo四模定位(四選三&#xff0c;BDS和GLONASS不能同時使用)。GPS02-UBX模塊能看到更多的衛星&#xff0c;有著更高的靈敏度&#xff0c;從而為用戶獲…

大模型日報 2024-07-04

大模型日報 2024-07-04 一、大模型資訊 大廠高管轉戰 AI 創業盤點&#xff1a;超 25 人&#xff0c;覆蓋全產業鏈&#xff0c;AI 應用最熱門 涉及多家互聯網大廠高管加入生成式 AI 創業&#xff0c;涵蓋多個領域及融資情況。 騰訊云發布自研大數據高性能計算引擎 Meson 軟硬一體…

Linux腳本自動安裝 docker

使用官方安裝腳本自動安裝 需使用 root 或sudu 權限賬戶安裝 安裝命令如下&#xff1a; curl -fsSL https://test.docker.com -o install-docker.shsudo sh install-docker.sh腳本中指令: –version 安裝指定版本 Use the --version option to install a specific version, f…

淺談chrome引擎

Chrome引擎主要包括其瀏覽器內核Blink、JavaScript引擎V8以及其渲染、網絡、安全等子系統。下面我將對這些關鍵部分進行簡要說明分析 1. Blink瀏覽器內核 Blink是Google開發的瀏覽器排版引擎&#xff0c;自Chrome 28版本起替代了Webkit作為Chrome的渲染引擎。Blink基于Webkit…

模余數最大公倍數

模余數最大公倍數 模余數題&#xff1a; 模余數 如果a%mb,則(am*k)%b。對m求模&#xff0c;余數為b的整數bm*k 題&#xff1a; 若干人&#xff0c;3001人為一排&#xff0c;余1人 4001人為一排&#xff0c;余2人 4999人為一排&#xff0c;余3人 求人數的最小值。 #include &l…

【Unity學習筆記】A*尋路算法

文章目錄 圖尋路算法BFS廣度優先算法DFS深度優先貪心算法 引入權重Dijkstra算法 A*算法C#實現步驟 Unity中的A*算法A*優化建議 圖 圖的知識盤點 pathfinding 作為一名計算機專業的學生&#xff0c;對于圖這種數據結構也是爛熟于心了。圖是一種包含了多個結點的數據結構&…

案例分享:數據集市搭建方案中集成SQLFlow數據血緣分析工具

本文中描述的數據集市搭建方案是一家跨國公司在AWS平臺上的具體實踐案例。我公司參與其中的數據血緣部分的建設&#xff0c;SQLFlow數據血緣分析工具在該方案中幫助用戶實現了數據血緣分析。 用戶使用Redshift 數據庫倉庫進行數據集市開發。從各種數據源提取數據&#xff0c;并…

動態代理(通俗易懂)

程序為什么需要代理&#xff1f;代理長什么樣&#xff1f; 例子 梳理 代理對象(接口)&#xff1a;要包含被代理的對象的方法 ---Star 被代理對象&#xff1a;要實現代理對象(接口) ---SuperStar 代理工具類&#xff1a;創建一個代理&#xff0c;返回值用代理對象&#xff0c…

羅克韋爾 AB 1756-OA16控制器 模塊 處理器

羅克韋爾 AB 1756-OA16該模塊是任何自動化系統的重要組成部分&#xff0c;提供對各種過程的精確控制。它被設計為易于安裝和使用&#xff0c;具有用戶友好的界面&#xff0c;允許簡單的配置和監控。 羅克韋爾 AB 1756-OA16控制器是一款為工業應用而設計的先進控制系統。它具有…

React快速入門-跟著AI學習react

React的快速入門可以遵循以下步驟進行&#xff0c;我將結合參考文章中的相關信息&#xff0c;以分點表示和歸納的形式給出詳細步驟&#xff1a; 一、React基礎知識了解 React的概念和特點&#xff1a; React是一個專注于構建用戶界面的JavaScript庫&#xff0c;采用聲明式設計…

python將多個文件夾里面的文件拷貝到一個文件夾中

網上可以搜到很多方式&#xff0c;有的好使&#xff0c;有的不好使&#xff0c;親測如下腳本可用&#xff0c;并可達到我想要的效果&#xff0c;只將多個文件夾里的文件拷貝到一個文件夾中&#xff0c;不拷貝文件夾本身&#xff0c;如果需要文件夾也拷貝打開注釋行即可 import…

初次使用GitHub教程入門

注冊一個github賬戶 訪問地址&#xff1a;https://github.com/&#xff0c;點擊右上角sign up&#xff0c;錄入以下信息&#xff0c;郵箱&#xff0c;密碼&#xff0c;賬號&#xff0c;會有郵箱驗證&#xff0c;跟著步驟來就好了 配置 本機上設置你的github的郵箱和用戶名 …

51-5 權限維持2 - 影子賬號(隱藏用戶)

權限維持技術 權限維持技術(Persistence,也稱為權限持久化)是一種能夠在系統重啟、用戶更改密碼或其他可能導致訪問中斷的情況下保持對系統訪問的技術。例如,它包括創建系統服務、利用計劃任務、修改系統啟動項或注冊表、以及映像劫持等方法。 創建影子賬戶 影子賬戶是指隱…

【管理咨詢寶藏139】某大型快消集團公司多渠道銷售管理體系方案

本報告首發于公號“管理咨詢寶藏”&#xff0c;如需閱讀完整版報告內容&#xff0c;請查閱公號“管理咨詢寶藏”。 【管理咨詢寶藏139】某大型快消集團公司多渠道銷售管理體系方案 【格式】PDF版本 【關鍵詞】羅蘭貝格、營銷咨詢、戰略規劃 【核心觀點】 - 銷售體系建設主要需…

谷粒商城學習-06-使用vagrant快速創建linux虛擬機

這一節的內容是在Windows上安裝虛擬機。 為什么要按照虛擬機呢&#xff1f; 原因是很多軟件只能在Linux下運行&#xff0c;有的雖然也可以在Windows上運行&#xff0c;但從安裝到運行會遇到很多問題&#xff0c;為這些解決這些問題花時間對于大多數人特別是初學者是沒有什么價…