二维矩阵的元素和

news2024/11/22 2:10:31

二维矩阵的元素和

    • 1.背景
    • 2.原理
    • 3.实现

1.背景

对矩阵元素进行求和,或者求子矩阵的元素和;给定矩阵左上角坐标(x1,y1)和右下角坐标(x2,y2); 如何快速求出 以(x1,y1),(x2,y2)围成的矩阵的元素和?

例如:有4x4矩阵A, 求A中所有元素和; 即求以左上角[0,0], 右下角[3,3]的矩阵的元素和
在这里插入图片描述
一种方法是暴力枚举,从左至右,从上至下依次加上每个元素:

int matrixElementSum(vector<vector<int>> &matrix, int x1,int y1, int x2, int y2) {
	int sum = 0;
	for (int i = x1; i <= x2; i++ ) {	/
		for (int j = y1; j <= y2; j++{
			sum += matrix[i][j];
		}
	}
	return sum
}

但是,如果需要求多个子矩阵的和,需要枚举多次,有没有一种方法,以O(1)的时间复杂度求出矩阵的元素和?可以通过预处理求出每个矩阵的元素和,然后让两个矩阵相减求得任意子矩阵的元素和。

2.原理

如何求得M的元素和?求前缀和再作差
首先,将矩阵M分成4块,
A:红色矩形
B:蓝色矩形
C:绿色矩形
D:紫色矩形
在这里插入图片描述
矩阵A、B、C、D的元素和记为 Sa,Sb,Sc,Sd; 那么矩阵M中所有元素的和S可以表示为:
S = Sc+Sb-Sa+Sd;
因为B, C中均包含了A, Sa加了两次,所以是Sb+Sc-Sa, 最后加上D部分的元素和Sd, 即为S的元素和;
S的递推式可以写成
S = Sc+Sb-Sa+Sd; C的右下角坐标(i-1,j), B的右下角坐标(i,j-1), A的右下角坐标(i-1,j-1), D的坐标(i,j), S的递推式

S[i][j] =  S[i][j-1] + S[i-1][j] - S[i-1][j-1] + M[i][j]; 

举个例子:
矩阵M如下图,矩阵M的元素和S, 矩阵下标从0开始, 根据上述递推公式
S[3][3] = S[3][2] + S[2][3] - S[2][2] + M[3][3]
在这里插入图片描述
以0,0为左上角,i,j (0 <= i <= m, 0 <= j <= n) 为右下角的矩阵元素和矩阵为
在这里插入图片描述

如果要求其中任意矩阵的元素和,例如右上角(1,1),坐下角(3,3)子矩阵的元素和, 即下图中子矩阵的元素和
在这里插入图片描述
可以用整个矩阵的元素和S,减去蓝色部分子矩阵元素和,减去绿色部分子矩阵元素和,加上红色部分子矩阵元素和(因为减了两次), 于是,上一张图中的矩阵元素和为
S1 = S[3][3] - S[3]0] - S[0][3] + S[0][0]
在这里插入图片描述
记右上角(row1,col1),坐下角(row2,col2), 子矩阵元素和计算公式
S1 = S[row2][col2] - S[row2][col2] - S[row1][col2] + S[row1][col1]

3.实现

#include<iostream>
#include<vector>
#include<string.h>
#define N 101
using namespace std;

int A[N][N];
int S[N][N];

int main() {
	int n = 6;
	memset(A,0,sizeof(A));
	memset(S,0,sizeof(S));
	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			A[i][j] = j+1;
			cout << A[i][j] << " ";
		}
		cout << endl; 
	}
	
	cout << "---sum---" << endl;
	//S[i][j] = S[i-1][j]+S[i][j-1]-S[i-1][j-1]+F[i][j] 
	//S[0][j] = S[0][j-1]+A[0][j]
	//S[i][0] = S[i-1][0]+A[i][0]
	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (i==0 && j==0) {
				S[i][j] = A[i][j]; 
			} else if (i==0) {
				S[i][j] = S[i][j-1] + A[i][j]; 	//A[0][j], 第一行 
			} else if(j==0) {
				S[i][j] = S[i-1][j] + A[i][j];	//A[i][0], 第一列 
			} else {
				S[i][j] = S[i-1][j] + S[i][j-1] - S[i-1][j-1] + A[i][j]; 
			}
			cout << S[i][j] << " ";
		}
		cout << endl;
	}
	
	cout << "---sub matrix sum---" << endl;
	//S1 = S[x2][y2] - S[x2][y1] - S[x1][y2] + S[x1][y1]
	
	int x1,x2,y1,y2;
	// 1 1 4 4
	cin >> x1 >> y1 >> x2 >> y2;
	
	int S1 = S[x2-1][y2-1] - S[x2-1][y1-1] - S[x1-1][y2-1] + S[x1-1][y1-1];
	cout << S1 << endl; 
	
	return 0;
} 

输出:
1 2 3 4
5 6 7 8
1 2 3 4
5 6 7 8
—sum—
1 3 6 10
6 14 24 36
7 17 30 46
12 28 48 72
—sub matrix sum—
1 1 4 4
51

参考:
https://www.bilibili.com/video/BV1oz4y1S7px?spm_id_from=333.880.my_history.page.click

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

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

相关文章

SAP入门技术分享五:内表

内表1. 概要2. 内表与表头3.内表的类型&#xff08;1&#xff09;类型&#xff08;2&#xff09;标准表&#xff08;3&#xff09;排序表&#xff08;4&#xff09;哈希表4.比较内表速度&#xff08;1&#xff09;标准表与排序表&#xff08;2&#xff09;二分法查找&#xff0…

Kafka生产者分区

生产者分区 分区的原因 (1&#xff09;便于合理使用存储资源&#xff0c;每个Patition在一个Broker上存储&#xff0c;可以把海量的数据按照分区切割成一块一块数据存储在多台Broker上。合理控制分区的任务&#xff0c;可以实现负载均衡的效果。 (2&#xff09;提高并行度&am…

如何设计一个消息队列?

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

用户登录、注册的简单案例: html+css+MyBatis+Servlet

用户登录一. 用户登录1. 流程与思路基本流程&#xff1a;详细过程&#xff1a;2. 准备环境建库建表Pojo实体类User&#xff1a;Maven坐标&#xff1a;mybatis核心配置文件&#xff1a;代理接口&#xff1a;3. 编写目录&#xff1a;HTML&#xff1a;Serlvet&#xff1a;4. 效果二…

【Leetcode】21. 合并两个有序链表

【Leetcode】21. 合并两个有序链表题目思路代码题目 思路 归并排序比较两个单链表每一个节点&#xff0c;将较小元素的节点值封装成一个新的节点添加到一个新的链表中如果两个单链表长度不一致&#xff0c;也就是有一个链表指针指向null ,那么将另一个链表中的所有节点全部添加…

【手写 Vue2.x 源码】第二十四篇 - 异步更新流程

一&#xff0c;前言 上篇&#xff0c;介绍了 Vue依赖收集的视图更新部分&#xff0c;主要涉及以下几点&#xff1a; 视图初始化时&#xff1a; render方法中会进行取值操作&#xff0c;进入 Object.defineProperty 的 get 方法get 方法中为数据添加 dep&#xff0c;并记录当…

20230115英语学习

Gold From Old Sim Cards Could Help Make Future Drugs SIM卡中回收的黄金&#xff0c;可用于制造药品 Chemists are paving a road to recycle discarded SIM cards, not for electronics, but for medicine. SIM cards, which allow your phone to connect to your netwo…

ATTCK 05

环境搭建 自行下载安装包 解压VMware中win7 win8 同样方法所要用到的攻击机为kali 调节kali的网络适配器为vmnet8 调节win7的网络适配器 增加vmnet5用来连接内网win8 vmnet5名称ip角色kali192.168.115.129攻击机win7192.168.115.150192.168.138.136win8192.168.138.138DC拓…

【 java 反射上篇】java反射机制不难吧?来看看这篇

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

BMS系统—产生原因如何工作

1 为什么需要BMS系统 1.1 介绍 1&#xff09;BMS&#xff0c;battery management system,电池管理系统 2&#xff09;BMS是一套嵌入式系统&#xff0c;由硬件和软件共同组成 3&#xff09;BMS功能&#xff1a;管理多节锂电池组成的电池包&#xff0c;实现充放电管理、安全保护…

jsp动物园网上购票系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 动物园网上购票系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统采用web模式开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#x…

Python:每日一题之FBI树(深度优先遍历)

题目描述 我们可以把由 “0” 和 “1” 组成的字符串分为三类&#xff1a;全 “0” 串称为 B 串&#xff0c;全 “1” 串称为 I 串&#xff0c;既含 “0” 又含 “1” 的串则称为 F 串。 FBI树是一种二叉树&#xff0c;它的结点类型也包括 F 结点&#xff0c;B 结点和 I 结点…

Anolis 8.6 部署 Kafka 3.3.1 安装和测试

龙蜥 8.6 安装 Kafka 3.3.1 并通过 SpringBoot 3.0.1 版本调试一.Kafka 安装1.下载编译后的文件2.拷贝到 Anolis 并解压3.启动服务3.常用命令1.Topic 增查删2.生产消费测试二.SpringBoot 连接 Kafka1.项目结构、依赖、配置文件和启动类2.生产者和生产监听3.消费者和消费监听4.自…

【Java寒假打卡】Java基础-并发工具类

【Java寒假打卡】Java基础-并发工具类HashMap在多线程下的问题ConcurrentHashMapCountDownLatchHashMap在多线程下的问题 package com.hfut.edu.test14;import com.sun.jdi.request.StepRequest;import java.util.HashMap;public class test2 {public static void main(String…

信号的时域和频域特性的区别到底是什么?

不严谨的说&#xff0c;时域和频域分析就是在不同的空间看待问题的&#xff0c;不同空间所对应的原子(基函数)是不同的。你想一下时域空间的基函数是什么&#xff1f;频域空间的基函数是什么&#xff1f;一般的时-频联合域空间的基函数是什么&#xff1f;小波域空间的基函数是什…

线索二叉树(c++)

1.引言&#xff1a; 二叉树的三种遍历方法能将二叉树中的结点按某种方式生成一个线性序列&#xff0c;能将一个非线性结构进行线性化操作。但随之也产生两个问题&#xff1a; 遍历效率低 在采用左右链表示方法作为二叉树的存储结构时&#xff0c;当二叉树更新后&#xff0c;并…

【博客586】ipvs的hook点位置以及hook点钩子函数剖析

ipvs的hook点位置以及hook点钩子函数剖析 ipvs实现负载均衡的基础 ipvs其实是基于netfilter框架来挂载hook点&#xff0c;从而对流量进行dnat等操作 ipvs的hook点剖析 IPVS的实现利用了Netfilter的三个Hook点&#xff0c;分别是&#xff1a;NF_INET_LOCAL_IN、NF_INET_LOCAL_O…

【nvidia CUDA 高级编程】NVSHMEM 直方图——复制式方法

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

pandas时间序列,案列

一&#xff1a;pandas时间序列 1.1为什么要学习pandas中的时间序列 不管在什么行业&#xff0c;时间序列都是一种非常重要的数据形式&#xff0c;很多统计数据以及数据的规律也都和时间序列有着非常重要的联系&#xff0c;而且在pandas中处理时间序列是非常简单的 1.2生成一段时…

【Python技巧】:cmd查看Python版本号居然与自己电脑装的版本不一致,特此提出解决方案

项目场景&#xff1a; 大家好&#xff01;欢迎大家看我的博客&#xff0c;最近学习Python的GUI&#xff08;PyQt5&#xff09;的时候发现了自己电脑的一个python问题&#xff0c;我本想装一下PyQt5&#xff0c;顺手查了一下自己电脑的Python版本&#xff0c;没想到居然是Python…