【数据结构】数组和字符串(一):矩阵的数组表示

news2024/9/29 8:08:00

文章目录

  • 4.1 数组
    • 4.1.1 数组的存储和寻址
    • 4.1.2 一维数组的基本操作
  • 4.2 矩阵
    • 4.2.1 矩阵的数组表示
      • a. 矩阵的二维数组存储及其乘法运算
      • b. 一维数组存储

4.1 数组

4.1.1 数组的存储和寻址

  数组是一种用于存储多个相同类型元素的数据结构。在内存中,数组的元素是连续存储的,可以通过下标来寻址和访问特定的元素。数组的存储通常是基于某种固定的数据类型,例如整数数组、字符数组等。关于数组的基础知识可参考前文:
【重拾C语言】六、批量数据组织(一)数组(数组类型、声明与操作、多维数组)

4.1.2 一维数组的基本操作

  一维数组的基本操作包括创建数组、访问数组元素、修改数组元素、插入元素、删除元素等。创建数组时需要指定数组的大小,然后可以使用索引来访问和修改数组中的元素。插入和删除元素通常移动其他元素以保持数组的连续性。

#include <stdio.h>

int main() {
    // 创建数组并初始化
    int array[5] = {1, 2, 3, 4, 5};

    // 访问数组元素
    int element = array[2];
    printf("访问数组中的第三个元素:%d\n", element);

    // 修改数组元素
    array[0] = 10;
    printf("修改数组中的第一个元素为:%d\n", array[0]);

    // 插入元素
    int newSize = 6;
    int position = 2;
    int newValue = 7;

    // 移动元素
    for (int i = newSize - 1; i > position; i--) {
        array[i] = array[i - 1];
    }

    // 插入新元素
    array[position] = newValue;
    newSize++;

    // 打印插入元素后的数组
    printf("插入元素后的数组:");
    for (int i = 0; i < newSize; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");

    // 删除元素
    int deletePosition = 3;

    // 移动元素
    for (int i = deletePosition; i < newSize - 1; i++) {
        array[i] = array[i + 1];
    }
    newSize--;

    // 打印删除元素后的数组
    printf("删除元素后的数组:");
    for (int i = 0; i < newSize; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");

    return 0;
}

输出:
在这里插入图片描述
  如上述结果所示,为数组提供越界索引保护是十分必要。在很多高级程序设计语言提供的数组类型没有越界索引保护,不检查数组的下标是否合法,如果索引越界且程序尝试访问由索引指定的元素,则可能访问任何随机内存位置中存放的数据。

4.2 矩阵

4.2.1 矩阵的数组表示

  矩阵是许多物理问题中出现的数学对象,是一种常用的数据组织方式。计算机工作者关心的是矩阵在计算机中如何存储,以及如何实现矩阵的基本操作。
  很自然会想到用二维数组存放矩阵,这也是矩阵存储的一个重要直观方法。此外,由前文可知,高级程序设计语言的二维数组采用按行优先次序顺序存储,因此也可以用一维数组来存放矩阵元素,存放次序是按行优先。换句话说,用规模为m×n的一维数组B来存放m行n列的二维矩阵A,且A中元素aij (1≤ i≤ m, 1 ≤ j ≤ n) 应存放在B[(i-1)×n+j-1] 处。
  数组的基本操作是数组加减,而矩阵的基本操作还有矩阵相乘和矩阵转置等。下面以矩阵乘法为例介绍矩阵的基本操作。矩阵的乘法运算略为复杂,对于矩阵Am×p和Bp×n的乘积Cm×n ,其第i行第j列元素cij的计算公式为 cij = Σ(ai1 * b1j + ai2 * b2j + … + aip * bpj)

a. 矩阵的二维数组存储及其乘法运算


#include <stdio.h>

void matrix_multiply(int A[][3], int B[][2], int C[][2], int m, int p, int n) {
    int i, j, k;
    
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            C[i][j] = 0;
            for (k = 0; k < p; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

void print_matrix(int matrix[][2], int rows, int cols) {
    int i, j;
    
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int A[2][3] = {{1, 2, 3},
                   {4, 5, 6}};
    int B[3][2] = {{7, 8},
                   {9, 10},
                   {11, 12}};
    int C[2][2];
    
    int m = 2;  // A的行数
    int p = 3;  // A的列数 / B的行数
    int n = 2;  // B的列数
    
    matrix_multiply(A, B, C, m, p, n);
    
    printf("Result:\n");
    print_matrix(C, m, n);
    
    return 0;
}
  • matrix_multiply的函数接受三个二维数组作为参数:ABC,以及三个整数mpn
    • 这些参数分别表示矩阵A的行数、矩阵A的列数(也是矩阵B的行数),以及矩阵B的列数。
    • 使用三个嵌套的循环来计算矩阵乘法:
      • 外层的两个循环变量ij分别用于遍历结果矩阵C的行和列。
      • 在每次迭代中,将矩阵C的当前元素初始化为0。
      • 然后,通过内层的循环变量k来遍历矩阵A的列和矩阵B的行,并将对应元素相乘并累加到矩阵C的当前元素上。

输出:
在这里插入图片描述

b. 一维数组存储

#include <stdio.h>

void flattenMatrix(int matrix[][3], int rows, int columns, int array[]) {
    int index = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            array[index] = matrix[i][j];
            index++;
        }
    }
}

int main() {
    int matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int rows = 3;
    int columns = 3;
    int array[rows * columns];

    flattenMatrix(matrix, rows, columns, array);

    // 输出一维数组
    for (int i = 0; i < rows * columns; i++) {
        printf("%d ", array[i]);
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1129665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频上的水印文字如何去掉?

嘿&#xff0c;大家好&#xff01;作为一个自媒体从业者&#xff0c;我相信大家都想知道如何去掉视频上的水印文字&#xff0c;想必大家和我一样每天都会在互联网寻找素材&#xff0c;而大部分图片或者视频都带有各种各样的水印&#xff0c;这给我的创作带来了不小的麻烦&#…

SQL Delete 语句(删除表中的记录)

SQL DELETE 语句 DELETE语句用于删除表中现有记录。 SQL DELETE 语法 DELETE FROM table_name WHERE condition; 请注意删除表格中的记录时要小心&#xff01;注意SQL DELETE 语句中的 WHERE 子句&#xff01; WHERE子句指定需要删除哪些记录。如果省略了WHERE子句&#xff…

【题解 单调队列优化dp】 简单的加法乘法计算题

题目描述&#xff1a; 分析&#xff1a; 由于对于每一步而言&#xff0c;我们都需要的是最小步数 所以我们很显然的可以写出一个dp方程&#xff1a; 设 f [ i ] f[i] f[i]表示达到i时的最小步数 我们有两种操作&#xff0c;也就是说我们可以通过一下两种方式转移过来&#xff…

前端开发实践:vue中用qrcode库将超链接生成二维码图片

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

VBA_MF系列技术资料1-212

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于定…

LinkedList概念+MyLinkedList的实现

文章目录 LinkedList笔记一、 LinkedList1.概念2.LinkedList的构造方法3.LinkedList的遍历 二、MyLinkedList的实现1.定义内部类2.打印链表、求链表长度、判断是否包含关键字3. 头插法和尾插法4.在任意位置插入5.删除结点6.清空链表 LinkedList笔记 一、 LinkedList 1.概念 L…

IAR For ARM 安装教程

电脑环境 安装包下载 1、官网下载 ①搜索 IAR ②切换产品&#xff0c;选择Arm ③选择IAR Embedded Workbench for Arm ④免费试用 2、网盘下载 EWARM-CD-8202-14838.exe(访问密码: 1666) https://url48.ctfile.com/f/33868548-961057458-611638?p1666 软件下载 1、点击安…

华为数通方向HCIP-DataCom H12-831题库(多选题:41-60)

第41题 下列哪些属于VLAN聚合的优点? A、增加了编址的灵活性 B、增加了可用的VLAN数量 C、减少了IP地址的浪费 D、实现Sub-VLAN间广播域的隔离 答案:ACD 解析: 各个Sub-VLAN作为一个独立广播域实现广播隔离,又节省了IP地址资源,提高了编址的灵活性 第42题 在进行结构化的…

【Java 进阶篇】Java Tomcat 入门指南

Java Tomcat&#xff08;通常简称 Tomcat&#xff09;是一个流行的开源Servlet容器&#xff0c;用于托管Java Web应用程序。它是Apache软件基金会的一部分&#xff0c;提供了一个稳定、可靠的环境来运行Java Servlets和JavaServer Pages&#xff08;JSP&#xff09;。本篇博客将…

mariadbmysql更改数据库默认存储路径

1.登录数据库查询默认存储位置 默认存储在/var/lib/mysql show variables like "%datadir%"; 2.先停止服务 systemctl stop mariadb 3.移动数据文件 mv /var/lib/mysql/ /home/ 4.修改服务配置 vim /etc/my.cnf.d/server.cnf5.在 [mysqld] 下面增加 datadir/ho…

4.2 QPainter的绘图接口介绍(下)

4.2 QPainter的绘图接口介绍(下) 上篇文章中我们举例介绍了drawRect、drawRoundRect、drawEllipse、drawArc、drawChord、drawPie这几个接口的用法,本篇文章继续讲解绘图的接口。 QPainter::drawText(绘制文字) 关于drawText的重载方法,我们可以将其分为两类来进行说明。…

基于Qt 的CAN Bus实现

# 简介 从 Qt5.8 开始,提供了 CAN Bus 类,假设您的 Qt 版本没有 CAN Bus,可以参考 Linux 应用编程来操控开发板的 CAN,目前我们主要讲解 Qt 相关的 CAN编程。其实 Qt 也提供了相关的 Qt CAN 的例子,我们也可以直接参考来编程。读者手上需要有测试 CAN 的仪器!否则写好程…

手机游戏定制研发手机软件开发

手机游戏定制研发是一个多阶段的过程&#xff0c;它使开发者能够根据客户的需求和创意&#xff0c;构建独特的游戏体验。这个领域是一个蓬勃发展的市场&#xff0c;因为手机游戏在全球范围内都备受欢迎。在本文中&#xff0c;我们将深入探讨手机游戏定制研发的主要步骤以及关键…

目标检测应用场景—数据集【NO.15】叶片虫害检测

写在前面&#xff1a;数据集对应应用场景&#xff0c;不同的应用场景有不同的检测难点以及对应改进方法&#xff0c;本系列整理汇总领域内的数据集&#xff0c;方便大家下载数据集&#xff0c;若无法下载可关注后私信领取。关注免费领取整理好的数据集资料&#xff01;今天分享…

python连接sqlserver

安装 pip install pyodbc 导入 import pyodbc 建立连接 con pyodbc.connect(DRIVER{SQL Server};SERVER192.168.202.173;DATABASEAIS20230802091529;UIDsa;PWDchief.cc1993) 游标 cursorcon.cursor() 查询 sql"select * from T_SAL_OUTSTOCK where FBillNoXSCKD…

GDB常用指令与调试汇总

文章目录 前言一、基础二、例子三、用gdb调试多线程程序 前言 GDB&#xff08;GNU Debugger&#xff09;是一个强大的调试工具&#xff0c;用于调试C、C等编程语言的程序。本文将介绍一些常用的GDB指令&#xff0c;以及通过例子演示如何使用这些指令进行程序调试。 一、基础 …

java--if语句

1.if语句 根据条件(真或假)来决定执行某段代码。 2.if语句有三种形式 执行流程&#xff1a; 首先判断条件表达式的结果&#xff0c;如果为true执行语句体&#xff0c;为false就不执行语句体。 注意事项&#xff1a; if语句中&#xff0c;如果大括号控制的只有一行代码&am…

【从0到1设计一个网关】网络通信框架Netty的设计

文章目录 Netty架构实现NettyHttpServer实现NettyHttpServerHandler实现NettyProcessor实现NettyHttpClient实现核心容器效果演示注:本文所有代码均已开源在Github上。 源码地址: 项目源码 完成当前章节后,代码效果演示如下: 这个请求将会重定向转发到我们后端的localhost…

woyaojiangzhang

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 博主接触FineReport帆软报表有一段时间了&#xff0c;正好前几天做了一个任务日历的需求&#xff0c;把每天完成的任务量直观的展示在日历上&#xff0c;方便管理者更好的监控各业务的完成情况&#xff0c;做完后想着…

S32K324 UDS Bootloader开发-需求篇

文章目录 前言内存分配UDS诊断协议需求CAN ID及时间参数UDS诊断服务Bootloader诊断服务APP诊断服务 DID22服务的DID:2E服务的DID:Routine Control DID&#xff1a; 刷写流程预编程主编程后编程 总结 前言 之前做过一个STM32的UDS Bootloader&#xff0c;协议栈主要是NXP官网下…