C++八股 —— 設計模式

文章目錄

    • 一、創建型模式
      • 1. 單例模式
      • 2. 工廠模式
    • 二、結構型模式
      • 1. 裝飾器模式
      • 2. 代理模式
    • 三、行為型模式
      • 1. 觀察者模式
      • 2. 策略模式

一、創建型模式

1. 單例模式

C++八股 —— 單例模式_c++ 單例模式-CSDN博客

2. 工廠模式

參考:【設計模式】工廠模式詳解-----簡單工廠模式、工廠方法模式、抽象工廠模式-CSDN博客

什么是工廠模式

工廠模式是一種創建型設計模式,它提供了一種創建對象的最佳方式,而無需暴露對象創建的邏輯細節。

工廠模式的三種類型

  1. 簡單工廠模式:一個工廠類根據傳入的參數決定創建哪種產品類的實例
  2. 工廠方法模式:定義一個創建對象的接口,但讓子類決定實例化哪個類
  3. 抽象工廠模式:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類

工廠模式的優點

  1. 封裝創建邏輯:將對象的創建與使用分離
  2. 代碼解耦:客戶端代碼不需要知道具體產品類的類名
  3. 易于擴展:添加新產品時,只需擴展工廠類,符合開閉原則
  4. 統一管理:可以對對象的創建進行統一的管理和控制

適用場景

  1. 當一個類不知道它所必須創建的對象的類時
  2. 當一個類希望由其子類來指定它所創建的對象時
  3. 當類將創建對象的職責委托給多個幫助子類中的某一個,并且你希望將哪一個幫助子類是代理者這一信息局部化時

簡單工程模式示例

#include <iostream>
#include <string>
#include <memory>// 產品接口
class Shape {
public:virtual void draw() = 0;virtual ~Shape() {}
};// 具體產品類
class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a Circle" << std::endl;}
};class Rectangle : public Shape {
public:void draw() override {std::cout << "Drawing a Rectangle" << std::endl;}
};class Triangle : public Shape {
public:void draw() override {std::cout << "Drawing a Triangle" << std::endl;}
};// 簡單工廠
class ShapeFactory {
public:static std::unique_ptr<Shape> createShape(const std::string& shapeType) {if (shapeType == "CIRCLE") {return std::make_unique<Circle>();} else if (shapeType == "RECTANGLE") {return std::make_unique<Rectangle>();} else if (shapeType == "TRIANGLE") {return std::make_unique<Triangle>();}return nullptr;}
};int main() {// 使用工廠創建對象auto circle = ShapeFactory::createShape("CIRCLE");auto rectangle = ShapeFactory::createShape("RECTANGLE");auto triangle = ShapeFactory::createShape("TRIANGLE");circle->draw();rectangle->draw();triangle->draw();return 0;
}

工廠方法模式

#include <iostream>
#include <memory>// 產品接口
class Button {
public:virtual void render() = 0;virtual void onClick() = 0;virtual ~Button() {}
};// 具體產品
class WindowsButton : public Button {
public:void render() override {std::cout << "Rendering a Windows button" << std::endl;}void onClick() override {std::cout << "Windows button clicked" << std::endl;}
};class WebButton : public Button {
public:void render() override {std::cout << "Rendering a Web button" << std::endl;}void onClick() override {std::cout << "Web button clicked" << std::endl;}
};// 創建者類
class Dialog {
public:virtual std::unique_ptr<Button> createButton() = 0;void render() {auto button = createButton();button->render();button->onClick();}virtual ~Dialog() {}
};// 具體創建者
class WindowsDialog : public Dialog {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WindowsButton>();}
};class WebDialog : public Dialog {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WebButton>();}
};int main() {std::unique_ptr<Dialog> dialog;// 根據配置或環境選擇創建者std::string config = "Windows"; // 可以改為 "Web" 來測試if (config == "Windows") {dialog = std::make_unique<WindowsDialog>();} else if (config == "Web") {dialog = std::make_unique<WebDialog>();}if (dialog) {dialog->render();}return 0;
}

抽象工程模式

#include <iostream>
#include <memory>// 抽象產品A
class Checkbox {
public:virtual void paint() = 0;virtual ~Checkbox() {}
};// 具體產品A1
class WindowsCheckbox : public Checkbox {
public:void paint() override {std::cout << "Rendering a Windows checkbox" << std::endl;}
};// 具體產品A2
class WebCheckbox : public Checkbox {
public:void paint() override {std::cout << "Rendering a Web checkbox" << std::endl;}
};// 抽象產品B
class Button {
public:virtual void paint() = 0;virtual ~Button() {}
};// 具體產品B1
class WindowsButton : public Button {
public:void paint() override {std::cout << "Rendering a Windows button" << std::endl;}
};// 具體產品B2
class WebButton : public Button {
public:void paint() override {std::cout << "Rendering a Web button" << std::endl;}
};// 抽象工廠
class GUIFactory {
public:virtual std::unique_ptr<Button> createButton() = 0;virtual std::unique_ptr<Checkbox> createCheckbox() = 0;virtual ~GUIFactory() {}
};// 具體工廠1
class WindowsFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WindowsButton>();}std::unique_ptr<Checkbox> createCheckbox() override {return std::make_unique<WindowsCheckbox>();}
};// 具體工廠2
class WebFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WebButton>();}std::unique_ptr<Checkbox> createCheckbox() override {return std::make_unique<WebCheckbox>();}
};// 客戶端代碼
class Application {
private:std::unique_ptr<GUIFactory> factory;std::unique_ptr<Button> button;std::unique_ptr<Checkbox> checkbox;public:Application(std::unique_ptr<GUIFactory> f) : factory(std::move(f)) {}void createUI() {button = factory->createButton();checkbox = factory->createCheckbox();}void paint() {if (button) button->paint();if (checkbox) checkbox->paint();}
};int main() {std::string config = "Windows"; // 可以改為 "Web" 來測試std::unique_ptr<GUIFactory> factory;if (config == "Windows") {factory = std::make_unique<WindowsFactory>();} else if (config == "Web") {factory = std::make_unique<WebFactory>();}if (factory) {auto app = Application(std::move(factory));app.createUI();app.paint();}return 0;
}

二、結構型模式

1. 裝飾器模式

核心思想動態地給一個對象添加一些額外的職責,而無需通過子類繼承。它通過創建一個包裝對象(即裝飾器)來包裹真實對象,提供了比繼承更有彈性的替代方案。

比喻:就像給一個禮物打包。你可以先裝盒子,再系絲帶,最后貼卡片。每個步驟都是在原有禮物的基礎上“裝飾”新的功能,而不是改變禮物本身。

優點

  • 無需創建大量子類即可擴展功能。
  • 可以在運行時動態地添加或撤銷功能。
  • 符合“開閉原則”(對擴展開放,對修改關閉)。

C++ 樣例
我們有一個簡單的Stream接口,我們需要動態地為其添加壓縮和加密的功能。

#include <iostream>
#include <string>// 組件接口
class Stream {
public:virtual void write(const std::string& data) = 0;virtual ~Stream() {}
};// 具體組件
class FileStream : public Stream {
public:void write(const std::string& data) override {std::cout << "Writing \"" << data << "\" to a file." << std::endl;}
};// 裝飾器基類
class StreamDecorator : public Stream {
protected:Stream* m_stream; // 持有一個組件對象的引用
public:StreamDecorator(Stream* stream) : m_stream(stream) {}virtual ~StreamDecorator() { delete m_stream; }
};// 具體裝飾器 - 壓縮
class CompressedStream : public StreamDecorator {
public:CompressedStream(Stream* stream) : StreamDecorator(stream) {}void write(const std::string& data) override {std::string compressedData = "Compressed(" + data + ")";m_stream->write(compressedData); // 調用被裝飾對象的方法}
};// 具體裝飾器 - 加密
class EncryptedStream : public StreamDecorator {
public:EncryptedStream(Stream* stream) : StreamDecorator(stream) {}void write(const std::string& data) override {std::string encryptedData = "Encrypted(" + data + ")";m_stream->write(encryptedData); // 調用被裝飾對象的方法}
};int main() {// 1. 簡單的文件流Stream* stream1 = new FileStream();stream1->write("Hello World");delete stream1;std::cout << "---------------" << std::endl;// 2. 動態添加功能:壓縮的文件流Stream* stream2 = new CompressedStream(new FileStream());stream2->write("Hello World");delete stream2;std::cout << "---------------" << std::endl;// 3. 動態添加更多功能:先加密再壓縮的文件流// 裝飾順序很重要!Stream* stream3 = new CompressedStream(new EncryptedStream(new FileStream()));stream3->write("Hello World");delete stream3;return 0;
}

輸出

Writing "Hello World" to a file.
---------------
Writing "Compressed(Hello World)" to a file.
---------------
Writing "Compressed(Encrypted(Hello World))" to a file.

2. 代理模式

核心思想:為另一個對象提供一個替身或占位符以控制對這個對象的訪問。

常見代理類型

  • 遠程代理:為一個對象在不同的地址空間提供局部代表(例如,RPC調用)。
  • 虛擬代理:根據需要創建開銷很大的對象(如圖片懶加載)。
  • 保護代理:控制對原始對象的訪問權限。
  • 智能引用代理:在對象被訪問時執行附加操作(如引用計數、日志記錄)。

C++ 樣例
虛擬代理:延遲加載大圖片。

#include <iostream>
#include <string>// 抽象主題
class Image {
public:virtual void display() = 0;virtual ~Image() {}
};// 真實主題
class RealImage : public Image {
private:std::string m_filename;void loadFromDisk() {std::cout << "Loading image: " << m_filename << " (This is an expensive operation!)" << std::endl;}
public:RealImage(const std::string& filename) : m_filename(filename) {loadFromDisk();}void display() override {std::cout << "Displaying image: " << m_filename << std::endl;}
};// 代理
class ProxyImage : public Image {
private:std::string m_filename;RealImage* m_realImage; // 代理持有一個對真實對象的引用public:ProxyImage(const std::string& filename) : m_filename(filename), m_realImage(nullptr) {}~ProxyImage() { delete m_realImage; }void display() override {// 只有在需要時才創建真實對象if (m_realImage == nullptr) {m_realImage = new RealImage(m_filename);}// 委托給真實對象執行請求m_realImage->display();}
};int main() {// 創建代理時,真實對象尚未創建,沒有昂貴的加載操作Image* image = new ProxyImage("test_10MB_photo.jpg");std::cout << "Image object created. Image not loaded yet." << std::endl;// 第一次調用display,真實對象被創建和加載image->display();std::cout << std::endl;// 后續調用,真實對象已存在,直接使用std::cout << "Second display call:" << std::endl;image->display();delete image;return 0;
}

輸出

Image object created. Image not loaded yet.
Loading image: test_10MB_photo.jpg (This is an expensive operation!)
Displaying image: test_10MB_photo.jpgSecond display call:
Displaying image: test_10MB_photo.jpg

三、行為型模式

1. 觀察者模式

核心思想:定義對象間的一種一對多的依賴關系,當一個對象(主題)的狀態發生改變時,所有依賴于它的對象(觀察者)都得到通知并被自動更新。又稱“發布-訂閱”模式。

比喻:報紙訂閱。出版社(主題)負責出版報紙。你(觀察者)向出版社訂閱后,一旦有新報紙出版,出版社就會自動送到你家。你也可以隨時取消訂閱。

C++ 樣例
使用現代C++的特性實現。

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>// 觀察者接口
class Observer {
public:virtual void update(int temperature) = 0;virtual ~Observer() {}
};// 主題(被觀察者)
class WeatherStation {
private:int m_temperature;std::vector<Observer*> m_observers; // 存儲觀察者指針public:void registerObserver(Observer* observer) {m_observers.push_back(observer);}void removeObserver(Observer* observer) {m_observers.erase(std::remove(m_observers.begin(), m_observers.end(), observer),m_observers.end());}void notifyObservers() {for (auto observer : m_observers) {observer->update(m_temperature);}}void setTemperature(int temp) {m_temperature = temp;std::cout << "Temperature updated to: " << temp << std::endl;notifyObservers(); // 狀態改變,通知所有觀察者}
};// 具體觀察者
class Display : public Observer {
public:void update(int temperature) override {std::cout << "[Display] Current temperature is: " << temperature << "°C" << std::endl;}
};class AlertSystem : public Observer {
public:void update(int temperature) override {if (temperature > 30) {std::cout << "[AlertSystem] Warning! Temperature is too high: " << temperature << "°C" << std::endl;}}
};int main() {WeatherStation station;Display display;AlertSystem alert;// 注冊觀察者station.registerObserver(&display);station.registerObserver(&alert);// 改變主題狀態,觸發通知station.setTemperature(25);std::cout << "-------------------" << std::endl;station.setTemperature(35);// 移除一個觀察者station.removeObserver(&alert);std::cout << "-------------------" << std::endl;std::cout << "After removing alert system:" << std::endl;station.setTemperature(40);return 0;
}

輸出

Temperature updated to: 25
[Display] Current temperature is: 25°C
[AlertSystem] Warning! Temperature is too high: 25°C
-------------------
Temperature updated to: 35
[Display] Current temperature is: 35°C
[AlertSystem] Warning! Temperature is too high: 35°C
-------------------
After removing alert system:
Temperature updated to: 40
[Display] Current temperature is: 40°C

2. 策略模式

核心思想:定義一系列算法,將每個算法封裝起來,并且使它們可以互相替換。策略模式讓算法的變化獨立于使用算法的客戶。

比喻:出行方式。去機場是一個目標(Context),你可以選擇不同的策略(Strategy):坐公交、打車、坐地鐵。你可以根據時間、金錢等因素輕松替換策略,而改變“去機場”這個行為本身。

優點

  • 避免使用多重條件判斷語句(if-else/switch-case)。
  • 算法可以自由切換和擴展。
  • 符合“開閉原則”。

C++ 樣例

#include <iostream>
#include <memory>
#include <vector>// 策略接口
class PaymentStrategy {
public:virtual void pay(int amount) = 0;virtual ~PaymentStrategy() {}
};// 具體策略
class CreditCardPayment : public PaymentStrategy {
private:std::string m_name;std::string m_cardNumber;
public:CreditCardPayment(const std::string& name, const std::string& cardNumber): m_name(name), m_cardNumber(cardNumber) {}void pay(int amount) override {std::cout << "Paid $" << amount << " using Credit Card (" << m_cardNumber << ")" << std::endl;}
};class PayPalPayment : public PaymentStrategy {
private:std::string m_email;
public:PayPalPayment(const std::string& email) : m_email(email) {}void pay(int amount) override {std::cout << "Paid $" << amount << " using PayPal (" << m_email << ")" << std::endl;}
};class CryptoPayment : public PaymentStrategy {
private:std::string m_walletAddress;
public:CryptoPayment(const std::string& address) : m_walletAddress(address) {}void pay(int amount) override {std::cout << "Paid $" << amount << " using Crypto (Address: " << m_walletAddress << ")" << std::endl;}
};// 上下文(Context)
class ShoppingCart {
private:std::vector<std::string> m_items;std::unique_ptr<PaymentStrategy> m_paymentStrategy;public:void addItem(const std::string& item) {m_items.push_back(item);}int calculateTotal() {// 簡化計算,假設每件商品10美元return m_items.size() * 10;}void setPaymentStrategy(std::unique_ptr<PaymentStrategy> strategy) {m_paymentStrategy = std::move(strategy);}void checkout() {int amount = calculateTotal();if (m_paymentStrategy) {m_paymentStrategy->pay(amount);std::cout << "Checkout successful! Enjoy your items." << std::endl;} else {std::cout << "Please set a payment method before checkout." << std::endl;}}
};int main() {ShoppingCart cart;cart.addItem("Book");cart.addItem("Laptop");cart.addItem("Mouse");int total = cart.calculateTotal();std::cout << "Total: $" << total << std::endl;// 用戶在運行時選擇支付策略int choice = 2; // 可以來自用戶輸入if (choice == 1) {cart.setPaymentStrategy(std::make_unique<CreditCardPayment>("John Doe", "1234-5678-9012-3456"));} else if (choice == 2) {cart.setPaymentStrategy(std::make_unique<PayPalPayment>("john.doe@example.com"));} else if (choice == 3) {cart.setPaymentStrategy(std::make_unique<CryptoPayment>("0xABC123..."));}cart.checkout();return 0;
}

輸出

Total: $30
Paid $30 using PayPal (john.doe@example.com)
Checkout successful! Enjoy your items.

:以上內容大部分由DeepSeek生成

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

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

相關文章

在openeuler中如何使用 firewalld 開放指定端口

在 OpenEuler 中使用 firewalld 開放指定端口的操作步驟如下&#xff0c;需區分臨時開放&#xff08;重啟后失效&#xff09;和永久開放&#xff08;重啟后保留&#xff09;兩種場景&#xff1a;一、查詢端口當前狀態首先確認端口是否已開放&#xff0c;避免重復配置&#xff1…

【Java進階】Java JIT 編譯器深度解析與優化實踐

Java JIT 編譯器深度解析與優化實踐Java JIT 編譯器深度解析與優化實踐一、JIT 編譯器核心原理1. JIT 工作流程2. 熱點代碼檢測機制二、Java 8 JIT 優化升級1. 分層編譯優化2. 方法內聯增強3. 循環優化升級4. 逃逸分析增強5. 向量化支持三、JIT友好代碼設計原則1. 方法設計優化…

【本地部署問答軟件Apache Answer】Answer開源平臺搭建:cpolar內網穿透服務助力全球用戶社區構建

文章目錄前言1. 本地安裝Docker2. 本地部署Apache Answer2.1 設置語言選擇簡體中文2.2 配置數據庫2.3 創建配置文件2.4 填寫基本信息3. 如何使用Apache Answer3.1 后臺管理3.2 提問與回答3.3 查看主頁回答情況4. 公網遠程訪問本地 Apache Answer4.1 內網穿透工具安裝4.2 創建遠…

華為數通認證學習

1、華為人才認證官網&#xff0c;https://e.huawei.com/cn/talent/portal/#/ 很全面的網站&#xff0c;包含了概述、了解認證、參加考試、學習資源、認證資訊四個板塊。可以了解華為認證的整個流程、下載學習資源&#xff08;培訓教材、視頻課程等&#xff09;&#xff0c;以及…

Android-ContentProvider的跨應用通信學習總結

一、ContentProvider的概念1. ContentProvider 是什么&#xff1f;&#xff08;核心概念&#xff09;ContentProvider 是 Android 四大組件之一。它的核心職責是管理和共享應用的結構化數據。我們可以把它想象成一個應用的**“數據大使館”**。在一個國家里&#xff08;Android…

Java數據結構第二十六期:解密位圖,海量數據處理的 “空間魔法”

專欄&#xff1a;Java數據結構秘籍 個人主頁&#xff1a;手握風云 目錄 一、位圖 1.1. 概念 1.2. 面試題 1.3. 位圖的實現 1.4. 位圖的應用 一、位圖 1.1. 概念 在數據結構中&#xff0c;位圖&#xff08;也稱為位數組、位向量或位集&#xff09;是一種緊湊的方式來表示一…

芯科科技即將重磅亮相IOTE 2025深圳物聯網展,以全面的無線技術及生態覆蓋賦能萬物智聯

作為低功耗無線連接領域的創新性領導廠商&#xff0c;Silicon Labs&#xff08;亦稱“芯科科技”&#xff09;將于8月27至29日攜其最前沿的人工智能&#xff08;AI&#xff09;和物聯網&#xff08;IoT&#xff09;解決方案在深圳舉辦的IOTE 2025國際物聯網展中盛大展出。這場亞…

Linux上安裝多個JDK版本,需要配置環境變量嗎

簡短回答&#xff1a;不需要同時配置多個 JDK 的 JAVA_HOME 和 PATH&#xff0c;但你可以安裝多個版本&#xff0c;并通過靈活的方式在它們之間切換。 文章目錄? 正確做法&#xff1a;安裝多個 JDK&#xff0c;但只讓一個生效&#xff08;通過環境變量或 alternatives&#xf…

MySQL有哪些高可用方案

大家好&#xff0c;我是鋒哥。今天分享關于【MySQL有哪些高可用方案】面試題。希望對大家有幫助&#xff1b; MySQL有哪些高可用方案? 超硬核AI學習資料&#xff0c;現在永久免費了&#xff01; MySQL 高可用方案是指確保 MySQL 數據庫在面對硬件故障、網絡故障、負載過重等…

【Windows】Windows平臺基于加速地址安裝vcpkg并集成到Visual Studio 2017

基礎運行環境 啟動&#xff1a; 適用于 VS 2017 的 x64 本機工具命令提示 ninja 下載壓縮包 https://gh-proxy.com/https:/github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-win.zip 直接解壓到c:/Windows (無需配置環境變量) CMake 下載安裝包 https://gh-proxy…

LLMs之MCP:Chrome MCP的簡介、安裝和使用方法、案例應用之詳細攻略

LLMs之MCP&#xff1a;Chrome MCP的簡介、安裝和使用方法、案例應用之詳細攻略 目錄 Chrome MCP的簡介 1、特點 2、與類似項目的比較 Chrome MCP的安裝和使用方法 1、安裝 2、使用方法 加載 Chrome 擴展 與 MCP 協議客戶端一起使用 使用 STDIO 連接&#xff08;替代方…

【Java EE】多線程-初階 synchronized 關鍵字 - 監視器鎖 monitor lock

synchronized 關鍵字 - 監視器鎖 monitor lock5. synchronized 關鍵字 - 監視器鎖 monitor lock5.1 synchronized 的特性5.2 synchronized 使??例5.3 Java 標準庫中的線程安全類本節?標? 掌握 synchronized關鍵字5. synchronized 關鍵字 - 監視器鎖 monitor lock &#xf…

Java多線程:從基礎到實戰

引言多線程是Java并發編程的核心技術之一&#xff0c;廣泛應用于服務器開發、數據處理、實時系統等領域。通過多線程&#xff0c;程序可以充分利用CPU資源&#xff0c;提高執行效率&#xff0c;同時處理多個任務。本文將從多線程的基本概念、實現方式、線程狀態、同步與通信到常…

list集合可以一邊遍歷一遍修改元素嗎?

今天看來一下Java中list集合部分的八股&#xff0c;發現了一個以前沒注意過的問題&#xff0c;記錄一下list可以一邊遍歷一邊修改元素嗎&#xff1f;答&#xff1a;在 Java 中&#xff0c;List在遍歷過程中是否可以修改元素取決于遍歷方式和具體的List實現類。①&#xff1a;對…

Infusing fine-grained visual knowledge to Vision-Language Models

Infusing fine-grained visual knowledge to Vision-Language Models Authors: Nikolaos-Antonios Ypsilantis, Kaifeng Chen, Andr Araujo, Ond?ej Chum Deep-Dive Summary: 視覺-語言模型中注入細粒度視覺知識 摘要 大規模對比預訓練產生了強大的視覺-語言模型&#xf…

RK3576賦能無人機巡檢:多路視頻+AI識別引領智能化變革

隨著工業巡檢任務的復雜度不斷提升&#xff0c;無人機逐漸取代傳統人工&#xff0c;成為電力、能源、林業、農業等行業的“高空作業主力”。然而&#xff0c;巡檢并非簡單的拍攝和回放&#xff0c;它要求無人機實時采集多路畫面、快速分析異常&#xff0c;并穩定回傳數據。這對…

ollama Modelfile 文件生成

輸入 根據如下TEMPLATE和params寫一個modelfile文件&#xff0c;TEMPLATE為&#xff1a;{{- $lastUserIdx : -1 -}} {{- range $idx, $msg : .Messages -}} {{- if eq $msg.Role “user” }}{{ $lastUserIdx $idx }}{{ end -}} {{- end }} {{- if or .System .Tools }}<|i…

關聯規則挖掘2:FP-growth算法(Frequent Pattern Growth,頻繁模式增長)

目錄 一、核心思想&#xff1a;一個形象的比喻 二、核心思想的具體拆解 步驟一&#xff1a;構建FP-tree&#xff08;頻繁模式樹&#xff09; 步驟二&#xff1a;從FP-tree中挖掘頻繁項集 為什么這很高效&#xff1f; 三、總結 核心思想與優勢 適用場景與缺點 四、例題…

在IDEA中DEBUG調試時查看MyBatis-Plus動態生成的SQL語句

在IDEA中DEBUG調試時查看MyBatis-Plus動態生成的SQL語句前言&#xff1a;動態SQL調試的痛與解決方案一、準備工作&#xff1a;調試前的檢查清單二、基礎方法&#xff1a;SqlSessionTemplate斷點調試步驟1&#xff1a;定位SqlSessionTemplate類步驟2&#xff1a;在invoke方法上設…

Linux 文本處理三劍客:awk、grep、sed 完全指南

Linux 文本處理三劍客&#xff1a;awk、grep、sed 完全指南 1. 概述 Linux 系統提供了三個強大的文本處理工具&#xff1a;awk、grep 和 sed&#xff0c;它們各有所長&#xff0c;結合使用可以高效地處理文本數據。 awk&#xff1a;擅長文本分析和格式化輸出&#xff0c;是一…