C++算法訓練營 Day10 棧與隊列(1)

1.用棧實現隊列

  • LeetCode:232.用棧實現隊列

請你僅使用兩個棧實現先入先出隊列。隊列應當支持一般隊列支持的所有操作(pushpoppeekempty):

實現 MyQueue 類:

void push(int x)將元素x推到隊列的末尾
int pop()從隊列的開頭移除并返回元素
int peek()返回隊列開頭的元素
boolean empty() 如果隊列為空,返回true;否則,返回false
說明:

你只能使用標準的棧操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty操作是合法的。
你所使用的語言也許不支持棧。你可以使用list或者deque(雙端隊列)來模擬一個棧,只要是標準的棧操作即可。

示例 1:

輸入:

[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”] [[], [1], [2], [],[], []]
輸出: [null, null, null, 1, 1, false]

解釋:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1 myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

  • 解題思路:

用棧來實現隊列的操作時我們應該要明白,棧有一個口,而隊列有兩個,因此棧只能先進后出,而隊列可以先進先出,因此棧需要兩個才能滿足隊列的先進先出。圖片來源:代碼隨想錄
在這里插入圖片描述

(1)push(int x)為入隊操作,其時間復雜度為O(1),可直接將新元素壓入輸入棧stIn,新元素總是添加到隊列尾部。

 void push(int x) {stIn.push(x);}

(2)pop() 為出隊操作,其平均時間復雜度為O(1)(最壞情況為O(n)),如果輸出棧stOut為空,就將輸入棧 stIn 所有元素轉移到stOut中,然后從stOut彈出并返回棧頂元素。

 int pop() {//確保輸出棧中有元素可用if (stOut.empty()) {//將輸入棧的所有元素轉移到輸出棧(反轉順序)while(!stIn.empty()) {stOut.push(stIn.top()); //復制棧頂元素stIn.pop();             //移除輸入棧頂元素}}int result = stOut.top(); //獲取輸出棧頂元素(隊列首部)stOut.pop();              //移除輸出棧頂元素return result;}

(3)peek()為查看隊首函數,其平均時間復雜度為O(1)(最壞情況為O(n)),在工業級別代碼開發中,最忌諱的就是實現一個類似的函數,直接把代碼粘過來改一改就完事了,這樣的項目代碼會越來越亂,因此我們需要復用pop()獲取元素,然后再將元素壓回輸出棧(因為peek操作不應移除元素)

int peek() {int res = this->pop(); //復用pop方法獲取元素stOut.push(res);       //將元素放回輸出棧(因為peek不移除元素)return res;}

其中this是一個指向當前對象的指針,在成員函數內部,可以通過this訪問當前對象的所有成員。因此this->pop()等價于直接調用pop(),顯式表示調用當前對象的pop成員函數。

由于peek()pop()都需要獲取隊列頭部元素,而pop()已經實現了:檢查并轉移棧元素(當stOut為空時)和返回隊列頭部元素,因此,不需要在peek()中重復相同的棧轉移邏輯,這樣寫可以避免邏輯重復,也就是我們之前說的:不能直接復制粘貼過來就完事了。

(4)empty()為檢查空隊列函數,時間復雜度為O(1),實現邏輯為當且僅當兩個棧都為空時隊列為空。

bool empty() {return stIn.empty() && stOut.empty(); //兩個棧都空時隊列為空}

完整代碼如下:

class MyQueue {
public:stack<int> stIn;  //輸入棧,用于接收新元素stack<int> stOut; //輸出棧,用于隊列操作//初始化隊列MyQueue() {} //構造函數不需要特別操作//將元素推入隊列尾部void push(int x) {stIn.push(x); //直接將新元素壓入輸入棧}//移除并返回隊列首部元素int pop() {//確保輸出棧中有元素可用if (stOut.empty()) {//將輸入棧的所有元素轉移到輸出棧(反轉順序)while(!stIn.empty()) {stOut.push(stIn.top()); //復制棧頂元素stIn.pop();             //移除輸入棧頂元素}}int result = stOut.top(); //獲取輸出棧頂元素(隊列首部)stOut.pop();              //移除輸出棧頂元素return result;}//獲取隊列首部元素(不移除) int peek() {int res = this->pop(); //復用pop方法獲取元素stOut.push(res);       //將元素放回輸出棧(因為peek不移除元素)return res;}//檢查隊列是否為空bool empty() {return stIn.empty() && stOut.empty(); //兩個棧都空時隊列為空}
};

2.用隊列實現棧

  • LeetCode:225.用隊列實現棧

請你僅使用兩個隊列實現一個后入先出(LIFO)的棧,并支持普通棧的全部四種操作(pushtoppopempty)。

實現MyStack類:

void push(int x)將元素x壓入棧頂。
int pop()移除并返回棧頂元素。
int top()返回棧頂元素。
boolean empty()如果棧是空的,返回true;否則,返回false

注意:

你只能使用隊列的標準操作 —— 也就是push to backpeek/pop from frontsizeis empty這些操作。
你所使用的語言也許不支持隊列。 你可以使用list(列表)或者deque(雙端隊列)來模擬一個隊列 , 只要是標準的隊列操作即可。

示例:

輸入: [“MyStack”, “push”, “push”, “top”, “pop”, “empty”] [[], [1], [2],[], [], []]
輸出: [null, null, null, 2, 2, false]

解釋:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

  • 解題思路:

由于隊列是先進先出,要想實現棧的后進先出,就需要將隊列前面的n - 1個元素依次重新插入隊列,然后將原隊尾元素出隊列即可。圖片來源:代碼隨想錄
在這里插入圖片描述

(1)push(int x) 為入棧操作,時間復雜度:為O(1)

 void push(int x) {//直接將新元素添加到隊列尾部que.push(x);}

(2)pop()為出棧操作,為時間復雜度O(n)

 int pop() {//獲取當前隊列中元素數量int size = que.size();//我們需要保留最后一個元素作為棧頂元素//所以需要旋轉 size-1 次size--;//旋轉隊列:將前 size-1 個元素移動到隊列尾部// 樣原隊列的最后一個元素就會成為隊列的第一個元素while (size--) {//將隊首元素添加到隊尾que.push(que.front());//移除原隊首元素que.pop();}//此時隊列的第一個元素就是棧頂元素int result = que.front();//移除棧頂元素(隊列的第一個元素)que.pop();return result;}

我們來模擬一下上述代碼流程:
假設我們執行三次push后調用pop,假設依次執行:

stack.push(1);
stack.push(2);
stack.push(3);
stack.pop();  // 移除并返回 3

步驟1:
初始狀態(push(1), push(2), push(3) 后)
隊列 que: [1, 2, 3] 1為隊首, 3為隊尾

步驟2:
計算旋轉次數

int size = que.size();  // size = 3
size--;                 // size = 2 (需要旋轉2次)

步驟3:
第一次旋轉 (size=2)

que.push(que.front());  // 將隊首1移到隊尾 → [1,2,3,1]
que.pop();              // 移除原隊首1 → [2,3,1]
// 隊列狀態: [2, 3, 1]

步驟4:
第二次旋轉 (size=1)

que.push(que.front());  // 將隊首2移到隊尾 → [2,3,1,2]
que.pop();              // 移除原隊首2 → [3,1,2]
// 隊列狀態: [3, 1, 2]

步驟5:
彈出棧頂元素

int result = que.front();   // result = 3 (棧頂元素)
que.pop();                  // 移除3 → [1, 2]
return result;              // 返回3

最終狀態:
隊列 que: [1, 2]
棧頂元素:2(下一次pop將返回2)

(3)top()為返回棧頂元素,其時間復雜度為O(n),執行步驟:

1.執行與 pop() 相同的旋轉操作
2.獲取棧頂元素但不移除
3.恢復隊列原始狀態: 將棧頂元素重新加入隊尾,然后移除隊列頭部的副本
4.返回棧頂元素

int top() {// 獲取當前隊列中元素數量int size = que.size();// 我們需要保留最后一個元素作為棧頂元素// 所以需要旋轉 size-1 次size--;// 旋轉隊列:將前 size-1 個元素移動到隊列尾部while (size--) {// 將隊首元素添加到隊尾que.push(que.front());// 移除原隊首元素que.pop();}// 此時隊列的第一個元素就是棧頂元素int result = que.front();// 關鍵步驟:為了保持棧的結構不變(因為我們只是查看棧頂元素,不是真的彈出)// 需要將棧頂元素重新放回隊列尾部que.push(que.front());// 然后移除隊列頭部的這個元素que.pop();// 返回棧頂元素return result;}

當然,也可以寫的更加簡便:

int top() {int res = this -> pop();que.push(res);return res;
}

(4)empty() 為檢查空棧,其時間復雜度為O(1)

 bool empty() {// 如果隊列為空,則棧也為空return que.empty();}

完整代碼如下:

class MyStack {
public:queue<int> que;  // 使用一個標準隊列來實現棧的功能// 構造函數,不需要特殊初始化MyStack() {// 構造函數體為空,因為隊列在聲明時已自動初始化}// 元素入棧(壓棧)操作// 時間復雜度:O(1)void push(int x) {// 直接將新元素添加到隊列尾部que.push(x);}// 元素出棧(彈棧)操作// 時間復雜度:O(n),因為需要旋轉隊列int pop() {// 獲取當前隊列中元素數量int size = que.size();// 我們需要保留最后一個元素作為棧頂元素// 所以需要旋轉 size-1 次size--;// 旋轉隊列:將前 size-1 個元素移動到隊列尾部// 這樣原隊列的最后一個元素就會成為隊列的第一個元素while (size--) {// 將隊首元素添加到隊尾que.push(que.front());// 移除原隊首元素que.pop();}// 此時隊列的第一個元素就是棧頂元素int result = que.front();// 移除棧頂元素(隊列的第一個元素)que.pop();// 返回被移除的棧頂元素return result;}// 獲取棧頂元素但不移除// 時間復雜度:O(n),因為需要旋轉隊列int top() {// 獲取當前隊列中元素數量int size = que.size();// 我們需要保留最后一個元素作為棧頂元素// 所以需要旋轉 size-1 次size--;// 旋轉隊列:將前 size-1 個元素移動到隊列尾部while (size--) {// 將隊首元素添加到隊尾que.push(que.front());// 移除原隊首元素que.pop();}// 此時隊列的第一個元素就是棧頂元素int result = que.front();// 關鍵步驟:為了保持棧的結構不變(因為我們只是查看棧頂元素,不是真的彈出)// 需要將棧頂元素重新放回隊列尾部que.push(que.front());// 然后移除隊列頭部的這個元素que.pop();// 返回棧頂元素return result;}// 檢查棧是否為空// 時間復雜度:O(1)bool empty() {// 如果隊列為空,則棧也為空return que.empty();}
};

3.有效的括號

  • LeetCode:20.有效的括號

給定一個只包括 '('')''{''}''['']' 的字符串s,判斷字符串是否有效。

有效字符串需滿足:

1.左括號必須用相同類型的右括號閉合。
2.左括號必須以正確的順序閉合。
3.每個右括號都有一個對應的相同類型的左括號。

示例 1:

輸入:s = “()”

輸出:true

示例 2:

輸入:s = “()[]{}”

輸出:true

示例 3:

輸入:s = “(]”

輸出:false

示例 4:

輸入:s = “([])”

輸出:true

  • 解題思路:

本題的核心思想是利用棧的先進后出特性進行括號匹配,即棧非常適合做對稱匹配類的題目

(1)首先由題可知,若想括號全部匹配,必須是兩兩對應的,即必須為偶數,否則奇數肯定會出現不匹配的情況,因此在開始,我們要先做一個偶數的判斷,其時間復雜度O(1)

if(s.size() % 2 != 0) return false;

(2)對棧進行初始化

stack<char> res;

(3)接著遍歷s中的每個字符,那么在開始之前,我們先要想明白,若是不匹配會出現哪幾種情況,這有利于我們書寫代碼的邏輯性和速度。
情況一:已經遍歷完了字符串,但是棧不為空,說明沒有相應的括號來匹配。
在這里插入圖片描述

情況二:遍歷字符串匹配的過程中,發現棧里沒有要匹配的字符。
在這里插入圖片描述

情況三:遍歷字符串匹配的過程中,棧已經為空了,沒有匹配的字符了,說明右括號沒有找到對應的左括號。
![(https://i-blog.csdnimg.cn/direct/5a3065f438f645a1b50f07a9b7d33f75.gif)

那么根據這三種情況就可以很快判斷出是否為有效括號,接下來我們如何來解決括號的匹配問題呢?由題目可知,左括號一定是先出現的,不然先出現右括號就沒有左括號與他匹配,那么根據這一點我們不難想到:

if(s[i] == '(') res.push(')');
else if(s[i] == '[') res.push(']');
else if(s[i] == '{') res.push('}');

即當我們遇到左括號時,將對應的右括號壓入棧中,依次記錄后續需要匹配的右括號類型。這些都完成后,我們就可以開始寫判斷是否為有效括號的部分了,那么(3)的整體代碼如下:

for(int i = 0; i < s.size(); ++i){if(s[i] == '(') res.push(')');else if(s[i] == '[') res.push(']');else if(s[i] == '{') res.push('}');// 情況三:遍歷字符串匹配的過程中,棧已經為空了,沒有匹配的字符了,說明右括號沒有找到對應的左括號// 情況二:遍歷字符串匹配的過程中,發現棧里沒有我們要匹配的字符。所else if(res.empty() || s[i] != res.top()) return false;else res.pop();
}return res.empty();// 情況一:此時我們已經遍歷完了字符串,若棧不為空,說明有相應的左括號沒有右括號來匹配

整體代碼如下所示:

class Solution {
public:bool isValid(string s) {if(s.size() % 2 != 0) return false;//如果s的長度為奇數,一定不符合要求stack<char> res;for(int i = 0; i < s.size(); ++i){if(s[i] == '(') res.push(')');else if(s[i] == '[') res.push(']');else if(s[i] == '{') res.push('}');// 第三種情況:遍歷字符串匹配的過程中,棧已經為空了,沒有匹配的字符了,說明右括號沒有找到對應的左括號 return false// 第二種情況:遍歷字符串匹配的過程中,發現棧里沒有我們要匹配的字符。所以return falseelse if(res.empty() || s[i] != res.top()) return false;else res.pop();}return res.empty();// 第一種情況:此時我們已經遍歷完了字符串,但是棧不為空,說明有相應的左括號沒有右括號來匹配,所以return false,否則就return true}
}; 

4.刪除字符串中的所有相鄰重復項

  • LeetCode:1047.刪除字符串中的所有相鄰重復項

給出由小寫字母組成的字符串s,重復項刪除操作會選擇兩個相鄰且相同的字母,并刪除它們。

s上反復執行重復項刪除操作,直到無法繼續刪除。

在完成所有重復項刪除操作后返回最終的字符串。答案保證唯一。

示例:

輸入:“abbaca”
輸出:“ca”
解釋:
例如,在 “abbaca” 中,我們可以刪除 “bb” 由于兩字母相鄰且相同,這是此時唯一可以執行刪除操作的重復項。之后我們得到字符串 “aaca”,其中又只有 “aa” 可以執行重復項刪除操作,所以最后的字符串為 “ca”。

  • 解題思路

(1)初始化棧

// 1. 使用棧存儲待匹配的字符
stack<char> sta;

(2)遍歷字符串:若當棧空或當前字符≠棧頂元素值時,將當前字符壓入棧中;若當前字符=棧頂 元素,則彈出棧頂元素,即刪除重復字母對。

// 2. 遍歷輸入字符串for(char c : s) {// 情況1: 棧空或當前字符與棧頂不同 → 壓棧if(sta.empty() || c != sta.top()) {sta.push(c);} // 情況2: 當前字符與棧頂相同 → 彈出棧頂(刪除重復對)else {sta.pop();}}

(3)構建結果:將棧中剩余字符彈出,此時彈出的結果為逆序,我們需要反轉操作,才能得到最終字符串。

// 3. 構建結果字符串string res = "";// 將棧中字符彈出(此時為逆序)while(!sta.empty()) {res += sta.top();sta.pop();}// 反轉得到正確順序reverse(res.begin(), res.end());return res;

運行過程如下圖所示:
在這里插入圖片描述
完整代碼如下所示:

class Solution {
public:string removeDuplicates(string s) {// 1. 使用棧存儲待匹配的字符stack<char> sta;// 2. 遍歷輸入字符串for(char c : s) {// 情況1: 棧空或當前字符與棧頂不同 → 壓棧if(sta.empty() || c != sta.top()) {sta.push(c);} // 情況2: 當前字符與棧頂相同 → 彈出棧頂(刪除重復對)else {sta.pop();}}// 3. 構建結果字符串string res = "";// 將棧中字符彈出(此時為逆序)while(!sta.empty()) {res += sta.top();sta.pop();}// 反轉得到正確順序reverse(res.begin(), res.end());return res;}
};

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

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

相關文章

設計模式域——軟件設計模式全集

摘要 軟件設計模式是軟件工程領域中經過驗證的、可復用的解決方案&#xff0c;旨在解決常見的軟件設計問題。它們是軟件開發經驗的總結&#xff0c;能夠幫助開發人員在設計階段快速找到合適的解決方案&#xff0c;提高代碼的可維護性、可擴展性和可復用性。設計模式主要分為三…

【QT】自定義QWidget標題欄,可拖拽(拖拽時窗體變為normal大小),可最小/大化、關閉(圖文詳情)

目錄 0.背景 1.詳細實現 思路簡介 .h文件 .cpp文件 0.背景 Qt Linux&#xff1b;項目遇到問題&#xff0c;解決后特此記錄 項目需要&#xff0c;個性化的標題欄&#xff08;是個widget&#xff09;&#xff0c;在傳統的三個按鈕&#xff08;最大化、最小化、關閉&#xf…

如何用 pnpm patch 給 element-plus 打補丁修復線上 bug(以 2.4.4 修復 PR#15197 為例)

背景 在實際項目開發中&#xff0c;依賴的三方庫&#xff08;如 element-plus&#xff09;難免會遇到 bug。有時候官方雖然已經修復&#xff0c;但新版本升級成本高&#xff0c;或者有兼容性風險。這時&#xff0c;給依賴打補丁是最優雅的解決方案之一。 本文以 element-plus…

Spring AI 入門:Java 開發者的生成式 AI 實踐之路

一、Spring AI 簡介 在人工智能技術快速迭代的今天&#xff0c;Spring AI 作為 Spring 生態系統的新生力量&#xff0c;正在成為 Java 開發者擁抱生成式 AI 的最佳選擇。該框架通過模塊化設計實現了與主流 AI 服務&#xff08;如 OpenAI、Anthropic&#xff09;的無縫對接&…

優化電腦的磁盤和驅動器提高電腦性能和延長硬盤壽命?

磁盤優化 磁盤清理&#xff1a; 使用系統自帶的磁盤清理工具&#xff08;如Windows的“磁盤清理”&#xff09;刪除不必要的文件。清空回收站。刪除臨時文件和緩存。 磁盤碎片整理&#xff08;針對機械硬盤&#xff09;&#xff1a; 定期進行磁盤碎片整理&#xff0c;以提高文…

EDA斷供危機下的冷思考:中國芯片設計軟件的破局之道優雅草卓伊凡

EDA斷供危機下的冷思考&#xff1a;中國芯片設計軟件的破局之道優雅草卓伊凡 一、EDA是什么&#xff1f;芯片行業的”隱形基石” 1.1 EDA技術解析 EDA&#xff08;Electronic Design Automation&#xff0c;電子設計自動化&#xff09;是用于設計和驗證集成電路的軟件工具鏈…

Jpackage

簡介 jpackage - 用于打包自包含 Java 應用程序的工具&#xff0c;是 JDK 14 引入的一個工具。 該工具將 Java 應用程序和 Java 運行時映像作為輸入&#xff0c;并生成包含所有必要依賴項的 Java 應用程序映像。它將能夠生成特定于平臺的格式的本機包&#xff0c;例如包括打包 …

CRM管理軟件的數據可視化功能使用技巧:讓數據驅動決策

在當今數據驅動的商業環境中&#xff0c;CRM管理系統的數據可視化功能已成為企業優化客戶管理、提升銷售效率的核心工具。據企銷客研究顯示&#xff0c;具備優秀可視化能力的CRM系統&#xff0c;用戶決策效率可提升47%。本文將深入解析如何通過數據可視化功能最大化CRM管理軟件…

智慧充電:新能源汽車智慧充電樁的發展前景受哪些因素影響?

全球能源結構轉型與碳中和目標的推進&#xff0c;新能源汽車產業迎來爆發式增長&#xff0c;而智慧充電樁作為其核心基礎設施&#xff0c;發展前景備受關注。智慧充電不僅關乎用戶充電體驗的優化&#xff0c;更是電網平衡、能源效率提升的關鍵環節。 然而&#xff0c;其發展并…

ABAP設計模式之---“簡單設計原則(Simple Design)”

“Simple Design”&#xff08;簡單設計&#xff09;是軟件開發中的一個重要理念&#xff0c;倡導以最簡單的方式實現軟件功能&#xff0c;以確保代碼清晰易懂、易維護&#xff0c;并在項目需求變化時能夠快速適應。 其核心目標是避免復雜和過度設計&#xff0c;遵循“讓事情保…

多模態大語言模型arxiv論文略讀(105)

UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ?? 論文標題&#xff1a;UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ?? 論文作者&#xff1a;Zhaowei…

SQLServer中的存儲過程與事務

一、存儲過程的概念 1. 定義 存儲過程&#xff08;Stored Procedure&#xff09;是一組預編譯的 SQL 語句的集合&#xff0c;它們被存儲在數據庫中&#xff0c;可以通過指定存儲過程的名稱并執行來調用它們。存儲過程可以接受輸入參數、輸出參數&#xff0c;并且可以返回執行…

使用UDP連接ssh

使用UDP連接ssh mosh簡介兩端安裝moshWindows安裝mosh 放行端口使用mosh登錄Linuxdebug mosh簡介 Mosh最大的特點是基于UDP方式傳輸&#xff0c;支持在服務端創建一個臨時的Key供客戶端一次性連接&#xff0c;退出后失效&#xff1b;也支持通過SSH的配置進行認證&#xff0c;但…

軟件功能模塊歸屬論證方法

文章目錄 **一、核心設計原則****二、論證方法****三、常見決策模式****四、驗證方法****五、反模式警示****總結** 在討論軟件功能點應該歸屬哪些模塊時&#xff0c;并沒有放之四海而皆準的固定方法&#xff0c;但可以通過系統化的論證和設計原則來做出合理決策。以下是常見的…

ServBay 1.13.0 更新,新增第三方反向代理/內網穿透

ServBay 作為一款簡化本地開發環境搭建與管理的強大工具&#xff0c;致力于打造一個開箱即用、穩定可靠的本地開發平臺&#xff0c;讓用戶專注于代碼編寫&#xff0c;提升開發效率。 ServBay 1.13.0 正式發布&#xff01;本次更新聚焦于提升本地開發項目的外部可訪問性、增強國…

如何利用樂維網管進行IP管理

IP管理是網絡管理中的關鍵環節&#xff0c;對于保障網絡的正常運行、提升資源利用效率以及保障網絡安全等方面都具有不可忽視的重要性。樂維網管在IP管理方面具有多種實用功能&#xff0c;以下從IP規劃與分配、IP狀態監測、IP沖突處理、IP審計與報表生成四個方面&#xff0c;介…

Go語言學習-->go的跨平臺編譯

Go語言學習–&#xff1e;go的跨平臺編譯 默認我們go build的可執行文件都是當前操作系統可執行的文件&#xff0c;Go語言支持跨平臺編譯——在當前平臺下編譯其他平臺的可執行文件。 eg&#xff1a;在windows界面的代碼&#xff0c;編譯完成后在linux上面運行 實現方式&#…

SpringBoot自動配置原理深度解析

一、引言 SpringBoot的"約定優于配置"理念極大地簡化了Spring應用的開發流程&#xff0c;而其核心魔法就是自動配置(Auto-Configuration)。本文將深入剖析自動配置的實現原理&#xff0c;幫助開發者更好地理解和定制SpringBoot應用。 二、自動配置核心機制 1. Ena…

使用阿里云百煉embeddings+langchain+Milvus實現簡單RAG

使用阿里云百煉embeddingslangchainMilvus實現簡單RAG 注意測試時&#xff0c;替換其中的key、文檔等 import os from langchain_community.embeddings import DashScopeEmbeddings from langchain_community.vectorstores import Milvus from langchain_text_splitters impor…

事件監聽 ——CAD C#二次開發

一、AutoCAD .NET API 事件機制 1. 事件監聽核心 - Database.ModifyObjects 事件 當數據庫中的實體&#xff08;如圖形對象&#xff09;發生修改時觸發&#xff0c;包括&#xff1a; - 幾何屬性變更&#xff08;移動、縮放、旋轉&#xff09;。 - 非幾何屬性變更&#xff08…