目录

矩阵的传统表示:二维数组

🔍 真正有用的数据是哪些?

从二维数组转为一维数组

用 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…