數據結構:對角矩陣(Diagonal Matrix)

目錄

矩陣的傳統表示:二維數組

🔍 真正有用的數據是哪些?

從二維數組轉為一維數組

用 C++ 類實現對角矩陣

1. 對角矩陣真正需要存什么?

2. 對角矩陣允許哪些行為?

3. 為什么要動態分配數組?

接下來推導每個函數如何實現


什么是對角矩陣?

在一個正方形矩陣中:只有主對角線(左上到右下)上的元素可能非零,其余全為零。

舉個例子:3x3 對角矩陣

A = | 1  0  0 || 0  2  0 || 0  0  3 |

只有 A[0][0], A[1][1], A[2][2] 非零,其余全是 0

?? 實質是一個表格,每個位置用兩個索引 ij 訪問:A[i][j]

矩陣的傳統表示:二維數組

在 C++ 里我們通常用二維數組來表示矩陣:

int A[3][3]; // 表示一個 3×3 的矩陣

例如:

A[0][0]  A[0][1]  A[0][2]
A[1][0]  A[1][1]  A[1][2]
A[2][0]  A[2][1]  A[2][2]

?總共有 n^2?個元素,每個都有自己的位置。

?問題來了:如果矩陣是稀疏的或有結構的,這個方式會浪費空間。

對角矩陣是一個非常特殊的矩陣:

  • 只有對角線(i == j)上的元素可能非 0

  • 其他所有元素(i ≠ j)都為 0

🔍 真正有用的數據是哪些?

觀察這個對角矩陣:

我們可以問自己兩個問題:

?哪些元素值我們真正關心?
?哪些元素值是注定為 0、不需要存?

答案很明顯:

條件是否有用存儲與否
i == j?是對角線 → 非零元素 → 必須存? 存
i ≠ j?一定是 0,無需存儲? 不存

所以,對角矩陣只需要存儲 n 個元素!

我們就可以只用一個 一維數組 存這些元素:

//只存儲對角線上的元素
int D[n];  // D[0] 存 A[0][0], D[1] 存 A[1][1], ..., D[n-1] 存 A[n-1][n-1]

從二維數組轉為一維數組

我們的問題是:

給定任意 (i, j),如何通過簡單規則判斷:

  • 要不要存儲?

  • 如果要 → 存在 D[] 中哪一項?

觀察這個矩陣:

A[0][0] A[0][1] A[0][2]
A[1][0] A[1][1] A[1][2]
A[2][0] A[2][1] A[2][2]

我們對每一個 (i, j) 做判斷:

  • 如果 i != j:一定是 0,不存

  • 如果 i == j:對角線 → 存在 D[i]

訪問時:如何從 (i,j) 得到實際值?

  • 如果 i == j:返回 D[i]

  • 如果 i != j:說明是非對角元素 ? 返回 0

int get(int D[], int i, int j) {if (i == j)return D[i];elsereturn 0;
}

插入時:如何通過 (i, j) 更新值?

  • 如果 i == j:表示是在對角線上,我們需要更新存儲數組 D[i] = value

  • 如果 i != j:不允許存儲,非對角線值必須為 0 ? 忽略或報錯

void set(int D[], int i, int j, int value) {if (i == j)D[i] = value;else if (value != 0)cout << "Error: Only diagonal elements can be non-zero.\n";
}

用 C++ 類實現對角矩陣

第一性思考:我們要封裝什么?

我們希望把對角矩陣的數據 + 行為都封裝起來,變成一個可用的抽象對象。

所以我們問自己三個關鍵問題:

1. 對角矩陣真正需要存什么?

  • 只需要存對角線上的元素:D[0]~D[n-1]

  • 也就是一個一維數組 + 大小信息

→ 數據成員:

int* D;     // 存儲數據(動態分配)
int n;      // 矩陣大小 n × n

2. 對角矩陣允許哪些行為?

行為也就是 成員函數(methods),我們一一推導:

功能描述
set(i, j, x)如果 i==j,設置 D[i]=x,否則忽略或報錯
get(i, j)如果 i==j 返回 D[i],否則返回 0
display()打印整個 n×n 矩陣
構造函數初始化數組大小和空間
析構函數釋放分配的堆內存

3. 為什么要動態分配數組?

  • 因為用戶可以創建任意大小的矩陣 n×n

  • 所以不能用靜態數組,必須用 new int[n] 動態分配

?抽象轉為結構:類的原型

class DiagonalMatrix {
private:int* D;   // 一維數組int n;    // 階數public:DiagonalMatrix(int size);           // 構造函數~DiagonalMatrix();                  // 析構函數void set(int i, int j, int value);  // 設置元素int get(int i, int j);              // 獲取元素void display();                     // 打印矩陣
};

接下來推導每個函數如何實現

1. 構造函數

目標:接受一個 size,創建一個對角矩陣

DiagonalMatrix::DiagonalMatrix(int size) {n = size;D = new int[n];      // 創建對角線存儲for (int i = 0; i < n; i++) D[i] = 0; // 初始化為 0
}

2. 析構函數

釋放堆空間,防止內存泄露:

DiagonalMatrix::~DiagonalMatrix() {delete[] D;
}

3. set(i, j, value)

void DiagonalMatrix::set(int i, int j, int value) {if (i >= 0 && i < n && j >= 0 && j < n) {if (i == j)D[i] = value;else if (value != 0)cout << "Error: only diagonal elements can be non-zero.\n";} else {cout << "Error: index out of bounds.\n";}
}

4. get(i, j)

int DiagonalMatrix::get(int i, int j) {if (i >= 0 && i < n && j >= 0 && j < n) {if (i == j)return D[i];elsereturn 0;} else {cout << "Error: index out of bounds.\n";return -1;}
}

5. display()

void DiagonalMatrix::display() {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (i == j)cout << D[i] << " ";elsecout << "0 ";}cout << endl;}
}

最終完整使用示例(main)

int main() {DiagonalMatrix dm(4); // 創建一個 4×4 的對角矩陣dm.set(0, 0, 5);dm.set(1, 1, 9);dm.set(2, 2, 3);dm.set(3, 3, 7);dm.set(0, 1, 99); // 應報錯:非對角元素dm.display();cout << "dm[2][2] = " << dm.get(2, 2) << endl;return 0;
}

總結(類設計第一性路徑圖)

對角矩陣↓
只需保存 D[0..n-1]↓
封裝成類 DiagonalMatrix↓
數據成員:- int* D  // 動態存儲對角線- int n   // 階數↓
方法設計:- 構造函數:new 分配- 析構函數:delete 釋放- set(i,j,x):僅 i==j 時設置- get(i,j):i==j 返回 D[i],否則 0- display():顯示整個矩陣

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

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

相關文章

Leetcode_349.兩個數組的交集

這道題的意思很明確&#xff0c;就是讓尋找兩個數組中的共同元素&#xff0c;并去重&#xff0c;由此可以聯想到哈希表的特性&#xff0c;注意到題目給的數據范圍&#xff0c;在1000以內&#xff0c;所以本題可以使用 STL 的庫函數&#xff0c;也可以使用數組進行模擬。 本題要…

STM32——寄存器映射

總 &#xff1a;STM32——HAL庫總結-CSDN博客 芯片資料&#xff1a; STM32F1系列參考手冊-V10&#xff08;中&#xff09; STM32F103ZET6(English) 一、寄存器基礎 1.1 簡介 單片機內部的控制機構。 像空氣開關控制電路一樣的原理&#xff0c;打開關閉某個開關&#xff0…

Java響應式編程

Java 響應式編程是一種基于異步數據流處理的編程范式&#xff0c;它強調數據流的聲明式構建和傳播變化的自動響應。Java 9 引入的Flow API為響應式編程提供了標準接口&#xff0c;而 Reactor 和 RxJava 等第三方庫則提供了更豐富的操作符和工具。核心概念Publisher&#xff08;…

【重學數據結構】二叉搜索樹 Binary Search Tree

目錄 二叉搜索樹的數據結構 手寫實現二叉搜索樹 樹節點定義 插入節點 源碼 流程圖 二叉樹插入步驟圖解 第一步: 插入 20 第二步: 插入 10 第三步: 插入 30 第四步: 插入 5 查找節點 源碼 場景一: 查找成功 (search for 25) 第一步: 從根節點開始 第二步:…

四、計算機組成原理——第1章:計算機系統概述

目錄 1.1計算機發展歷程 1.1.1計算機硬件的發展 1.計算機的四代變化 2.計算機元件的更新換代 1.1.2計算機軟件的發展 1.2計算機系統層次結構 1.2.1計算機系統的組成 1.2.2計算機硬件 1.馮諾依曼機基本思想 2.計算機的功能部件 (1)輸入設備 (2)輸出設備 (3)存儲器 (4)運算器 (5)…

flutter TextField 失去焦點事件

在 Flutter 中&#xff0c;處理 TextField 的失去焦點事件&#xff08;即失去焦點時觸發的操作&#xff09;通常有兩種常用方式&#xff1a;使用 FocusNode 或 onEditingComplete 回調。以下是具體實現&#xff1a; import package:flutter/material.dart;class MyTextField e…

Moonlight for ChromeOS 常見問題解決方案

Moonlight for ChromeOS 常見問題解決方案 項目基礎介紹 Moonlight for ChromeOS 是一個開源的 NVIDIA GameStream 客戶端&#xff0c;允許用戶將他們的游戲從高性能的桌面電腦流式傳輸到運行 ChromeOS 的設備上。該項目還支持 Android 和 iOS/tvOS 平臺。Moonlight for Chrome…

SQL語句:讀操作、寫操作、視圖

文章目錄讀操作分類基礎查詢語句示例高級查詢--分組查詢、子查詢、表連接、聯合查詢分組查詢&#xff1a;子查詢&#xff08;嵌套查詢&#xff09;表連接聯合查詢寫操作視圖SQL&#xff1a;結構化查詢語言讀操作 重點是where查詢&#xff0c;即高級查詢部分 分類 DML &#…

Python 機器學習實戰:基于 Scikit-learn

本文圍繞《Python 機器學習實戰&#xff1a;基于 Scikit-learn 的項目開發》展開&#xff0c;先介紹 Scikit-learn 庫的基礎特性與優勢&#xff0c;再闡述機器學習項目開發的完整流程&#xff0c;包括數據收集與預處理、模型選擇與訓練、評估與優化等。通過具體實戰案例&#x…

java里List鏈式編程

java里對list的操作&#xff0c;我們一遍使用for遍歷&#xff0c;輸出或改變里面的內容。單經常在代碼里面我們發現&#xff0c;也可以使用這樣的代碼結構daPaymentActionVo.setApnolist(paymentActionVo.getApnolist().stream().map(PaymentActionVo.Voucher::getApno).collec…

【esp32s3】7 - VSCode + PlatformIO + Arduino + 構建項目

一、PlatformIO 1.1. 概述 官方文檔&#xff1a;What is PlatformIO? PlatformIO 是一個跨平臺的物聯網開發生態系統&#xff0c;專門為嵌入式系統開發設計&#xff0c;支持多種開發板和框架。 1.1.1. 主要特點 跨平臺&#xff1a;支持 Windows、macOS 和 Linux多框架支持&…

LE AUDIO CIS/BIS音頻傳輸時延的計算

LE AUDIO音頻總時延計算方法 按照BAP的規范,LE AUDIO音頻總延時包括三個部分:Audio Processing Time,Transport Latency,Presentation Delay。如下圖所示是播放音樂的示例圖: 這里還有一個麥克風錄音的總時延示例圖: Audio Processing Time:這個就是音頻DSP獲取音頻數…

git 修改 更新

git 修改 更新先更新&#xff0c;后修改# 暫存當前修改 git add . git stash# 獲取最新的 main 分支 git checkout main git pull# 新建開發分支 git checkout -b lbg_0727# ?? 先把 main 的最新代碼合并/變基到當前分支&#xff08;用于消除沖突&#xff09; # 方法1&#x…

飛鶴困局:增長神話的裂痕

增長天花板已然逼近&#xff0c;飛鶴需要探尋新方向。作者|安德魯編輯|文昌龍“飛鶴&#xff0c;更適合中國寶寶體質”——這句曾讓無數媽媽點頭的廣告語&#xff0c;幫飛鶴坐上了中國奶粉市場的頭把交椅。可多年后&#xff0c;時代紅利退潮&#xff0c;故事不好講了。飛鶴的利…

Java設計模式之<建造者模式>

目錄 1、建造者模式 2、建造者模式結構 3、實現 4、工廠模式對比 5、適用場景差異 前言 建造者模式是一種創建型設計模式。用于封裝復雜對象的構建過程&#xff0c;通過步驟構建產品類。它包括產品類、抽象建造者、具體建造者和指揮者角色。 優點在于靈活性、解耦和易擴展…

fchown/fchownat系統調用及示例

55. fchmod - 通過文件描述符改變文件權限 函數介紹 fchmod是一個Linux系統調用&#xff0c;用于通過文件描述符來改變文件的訪問權限。它是chmod函數的文件描述符版本&#xff0c;避免了路徑名解析。 函數原型 #include <sys/stat.h> #include <unistd.h>int fchm…

20250726-5-Kubernetes 網絡-Service 代理模式詳解(iptables與ipvs)_筆記

一、服務三種常用類型 ?? 1. LoadBalancer類型 工作原理:與NodePort類似,在每個節點上啟用端口暴露服務,同時Kubernetes會請求底層云平臺(如阿里云、騰訊云、AWS等)的負載均衡器,將每個Node([NodeIP]:[NodePort])作為后端添加。 自動化實現:云廠商通過官方實現的控制…

horizon置備出錯

報錯內容如下&#xff1a; [2025/7/28 19:15] 置備 Customization failure: Customization of the guest operating system is not supported due to the given reason: 期間出錯 解決方法&#xff1a;將模板轉換為虛擬機&#xff0c;安裝vmtools&#xff1b;再安裝vmtools之后…

【unitrix】 6.19 Ord特質(ord.rs)

一、源碼 這段代碼定義了一個標記特征&#xff08;marker trait&#xff09;Ord 和三個實現&#xff0c;用于將類型標記與 Rust 標準庫中的 Ordering 枚舉關聯起來。 use crate::sealed::Sealed; use core::cmp::Ordering; use crate::number::{Greater, Equal, Less}; /// 用于…

數據結構之順序表鏈表棧

順序表 什么是 list list 的使用 線性表是什么 順序表是什么 順序表和線性表的關系 順序表和數組的區別 List 和 ArrayList 的關系 如何自己模擬實現 myArrayList ArrayList 的構造 ArrayList 的常見方法 以下兩種寫法有什么區別 ArrayList<Integer> arrayLis…