基于C#实现三元组

我们知道矩阵是一个非常强大的数据结构,在动态规划以及各种图论算法上都有广泛的应用,当然矩阵有着不足的地方就是空间和时间复杂度都维持在 N2 上,比如 1w 个数字建立一个矩阵,在内存中会占用 1w*1w=1 亿的类型空间,这时就会遇到 outofmemory。。。那么面临的一个问题就是如何来压缩矩阵,当然压缩的方式有很多种,这里就介绍一个顺序表的压缩方式:三元组。

一、三元组

有时候我们的矩阵中只有零星的一些非零元素,其余的都是零元素,那么我们称之为稀疏矩阵,当然没有绝对的说有多少个零元素才算稀疏。
image.png
针对上面的这个无规律的存放非零元素,三元组提出了一种方法,就是仅仅记录矩阵中的非零元素以及它的行,列以及值 N(x,y,v)构成的一个三元组,标识一个稀疏矩阵的话,还要记录该矩阵的阶数,这样我们就将一个二维的变成了一个一维,极大的压缩的存储空间,这里要注意的就是,三元组的构建采用“行“是从上到下,“列”也是从左到右的方式构建的顺序表。
image.png

 /// <summary>
 /// 三元组
 /// </summary>
 public class Unit
 {
     public int x;
     public int y;
     public int element;
 }

 /// <summary>
 /// 标识矩阵
 /// </summary>
 public class SPNode
 {
     //矩阵总行数
     public int rows;

     //矩阵总列数
     public int cols;

     //非零元素的个数
     public int count;

     //矩阵中非零元素
     public List<Unit> nodes = new List<Unit>();
 }

其实说到这里也就差不多了,我们只要知道三元组是用来做矩阵压缩的一个顺序存储方式即可,然后知道怎么用三元组表来做一些常规的矩阵运算,好了,既然说已经做成线性存储了,那就做个“行列置换”玩玩。

二、行列置换

做行列置换很容易,也就是交换"非零元素"的(x,y)坐标,要注意的就是,原先我们的三元组采用的是”行优先“,所以在做转置的时候需要遵循"列优先“。
image.png

 /// <summary>
 /// 行转列运算
 /// </summary>
 /// <param name="spNode"></param>
 /// <returns></returns>
 public SPNode ConvertSpNode(SPNode spNode)
 {
     //矩阵元素的x和y坐标进行交换
     SPNode spNodeLast = new SPNode();

     //行列互换
     spNodeLast.rows = spNode.cols;
     spNodeLast.cols = spNode.rows;
     spNodeLast.count = spNode.count;

     //循环原矩阵的列数 (行列转换)
     for (int col = 0; col < spNode.cols; col++)
     {
         //循环三元组行的个数
         for (int sp = 0; sp < spNode.count; sp++)
         {
             var single = spNode.nodes[sp];

             //找到三元组中存在的相同编号
             if (col == single.y)
             {
                 spNodeLast.nodes.Add(new Unit()
                 {
                     x = single.y,
                     y = single.x,
                     element = single.element
                 });
             }
         }
     }

     return spNodeLast;
 }

最后是总的代码:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Diagnostics;
 using System.Threading;
 using System.IO;
 
 namespace ConsoleApplication2
 {
     public class Program
     {
         public static void Main()
         {
            Martix martix = new Martix();
 
             //构建三元组
             var node = martix.Build();
 
             foreach (var item in node.nodes)
             {
                 Console.WriteLine(item.x + "\t" + item.y + "\t" + item.element);
             }
 
             Console.WriteLine("******************************************************");
 
             var mynode = martix.ConvertSpNode(node);
 
             foreach (var item in mynode.nodes)
             {
                 Console.WriteLine(item.x + "\t" + item.y + "\t" + item.element);
             }
 
             Console.Read();
         }
     }
 
     public class Martix
     {
         /// <summary>
         /// 三元组
         /// </summary>
         public class Unit
         {
             public int x;
             public int y;
             public int element;
         }
 
         /// <summary>
         /// 标识矩阵
         /// </summary>
         public class SPNode
         {
             //矩阵总行数
             public int rows;
 
             //矩阵总列数
             public int cols;
 
             //非零元素的个数
             public int count;
 
             //矩阵中非零元素
             public List<Unit> nodes = new List<Unit>();
         }
 
         /// <summary>
         /// 构建一个三元组
         /// </summary>
         /// <returns></returns>
         public SPNode Build()
         {
             SPNode spNode = new SPNode();
 
             //遵循行优先的原则
             spNode.nodes.Add(new Unit() { x = 0, y = 0, element = 8 });
             spNode.nodes.Add(new Unit() { x = 1, y = 2, element = 1 });
             spNode.nodes.Add(new Unit() { x = 2, y = 3, element = 6 });
             spNode.nodes.Add(new Unit() { x = 3, y = 1, element = 4 });
 
             //4阶矩阵
             spNode.rows = spNode.cols = 4;
 
             //非零元素的个数
             spNode.count = spNode.nodes.Count;
 
             return spNode;
         }
 
         /// <summary>
         /// 行转列运算
         /// </summary>
         /// <param name="spNode"></param>
         /// <returns></returns>
         public SPNode ConvertSpNode(SPNode spNode)
         {
             //矩阵元素的x和y坐标进行交换
             SPNode spNodeLast = new SPNode();
 
             //行列互换
             spNodeLast.rows = spNode.cols;
             spNodeLast.cols = spNode.rows;
             spNodeLast.count = spNode.count;
 
             //循环原矩阵的列数 (行列转换)
             for (int col = 0; col < spNode.cols; col++)
             {
                 //循环三元组行的个数
                 for (int sp = 0; sp < spNode.count; sp++)
                 {
                     var single = spNode.nodes[sp];
 
                     //找到三元组中存在的相同编号
                     if (col == single.y)
                     {
                         spNodeLast.nodes.Add(new Unit()
                         {
                             x = single.y,
                             y = single.x,
                             element = single.element
                         });
                     }
                 }
             }
 
             return spNodeLast;
         }
     }
 }

image.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【人工智能】Chatgpt的训练原理

前言 前不久&#xff0c;在学习C语言的我写了一段三子棋的代码&#xff0c;但是与我对抗的电脑是没有任何思考的&#xff0c;你看了这段代码就理解为什么了&#xff1a; void computerMove(char Board[ROW][COL], int row, int col) {while (1){unsigned int i rand() % ROW, …

BC76 [NOIP2008]ISBN号码

#include<stdio.h> int main() {char arr[13]; //存放13位的ISBNint i, j;scanf("%s",arr);int s 0;for(i0, j1; i<11; i){if(arr[i] ! -){s (arr[i]-0)*j; //将字符换成int累加&#xff1a;0162……29158j; //执行if的时候加&#xff0c;不执行不加…

Linxu 进程替换

进程替换的背景&#xff1a; 进程的替换我们需要调用execl这个接口,exxecl在3号手册&#xff0c;属于系统接口。 调用系统命令 execl 为了方便理解execl的作用&#xff0c;我们写一个程序&#xff1a; 单进程替换 我们发现运行结果是通过c库里的exec接口把系统命令 "l…

【深度学习】DAMO-YOLO,阿里,701类通用检测模型,目标检测

https://github.com/tinyvision/DAMO-YOLO/blob/master/README_cn.md DAMO-YOLO是由阿里巴巴达摩院智能计算实验室TinyML团队开发的一个兼顾速度与精度的目标检测框架,其效果超越了目前的一众YOLO系列方法&#xff0c;在实现SOTA的同时&#xff0c;保持了很高的推理速度。DAMO…

Error PostCSS plugin autoprefixer requires PostCSS 8

文章目录 一、情况一二、情况二三、总结 在启动 vue项目时&#xff0c;突然控制台报错&#xff1a; Error: PostCSS plugin autoprefixer requires PostCSS 8。然后依次出现下面几种情况&#xff0c;依次解决完&#xff0c;项目就可以正常启动了 一、情况一 error in ./src/…

【涂鸦T2-U】1、开发环境搭建

前言 本章介绍T2-U的开发环境搭建流程&#xff0c;以及一些遇到的问题。 一、资料 试用网址&#xff1a; 【新品体验】涂鸦 T2-U 开发板免费试用 涂鸦官网文档&#xff1a; 涂鸦 T2-U 开发板 T2-U 模组规格书 T2-U 开发板 淘宝(资料较全)&#xff1a; 涂鸦智能 TuyaOS开发…

软件测试职业规划导图

公司开发的产品专业性较强&#xff0c;软件测试人员需要有很强的专业知识&#xff0c;现在软件测试人员发展出现了一种测试管理者不愿意看到的景象&#xff1a; 1、开发技术较强的软件测试人员转向了软件开发(非测试工具开发)&#xff1b; 2、业务能力较强的测试人员转向了软件…

基于单片机的肺活量检测系统(论文+源码)

1.系统设计 在基于单片机的肺活量检测系统中&#xff0c;在硬件上整个系统通过利用主控制器STC89C52单片机来实现对整个系统进行控制的功能&#xff0c;通过采用LCD1602实现实时液晶显示数据的功能&#xff0c;通过肺活量传感器XGZP6847ADC0832实现监测肺活量的工作&#xff0…

ESP32网络开发实例-远程Web串口监视器

远程Web串口监视器 文章目录 远程Web串口监视器1、应用介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将构建一个 ESP32 网络服务器,用作远程串行监视器。 基于 Web 的串行监视器的工作方式与通常用于调试目的的 Arduino IDE 串行监视器的工作方式相同。 1、应用介绍 …

系列十六、Spring IOC容器的扩展点

一、概述 Spring IOC容器的扩展点是指在IOC加载的过程中&#xff0c;如何对即将要创建的bean进行扩展。 二、扩展点 2.1、BeanDefinitionRegistryPostProcessor 2.1.1、概述 BeanDefinitionRegistryPostProcessor是bean定义的后置处理器&#xff0c;在BeanDefinition加载后&a…

cesium轨迹线(闪烁轨迹线)

cesium轨迹线(闪烁轨迹线) 下面有源码 实现思路 使用ellipse方法加载圆型,修改polyline中‘material’方法重写glsl来实现当前效果(cesium版本1.109) 示例代码 index.html <!DOCTYPE html> <html lang="en"><head

MyBatis框架_01

Web后端开发_03 MyBatis框架 什么是MyBatis? MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发。MyBatis本是 Apache的一个开源项目iBatis&#xff0c;2010年这个项目由apache迁移到了google code&#xff0c;并且改名为MyBatis 。2013年11月迁移到Github。官网…

基于Pytest+Requests+Allure实现接口自动化测试

一、整体结构 框架组成&#xff1a;pytestrequestsallure 设计模式&#xff1a; 关键字驱动 项目结构&#xff1a; 工具层&#xff1a;api_keyword/ 参数层&#xff1a;params/ 用例层&#xff1a;case/ 数据驱动&#xff1a;data_driver/ 数据层&#xff1a;data/ 逻…

crontab计划任务

银河麒麟v10服务器版和桌面版执行周期计划任务分为两类&#xff1a;系统任务调度和用户任务调度。系统任务是由 cron (crond) 这个系统服务来控制的&#xff0c;这个系统服务是默认启动的&#xff0c;通过vim /etc/crontab执行。用户自己设置的计划任务则使用crontab 命令 配置…

SpringMVC系列-7 @CrossOrigin注解与跨域问题

背景 前段时间帮同事分析了一个跨域问题&#xff0c;正好系统分析和整理一下。 1.跨域 理解同源策略是理解跨域的前提。同源策略定义如下&#xff1a; 在同一来源的页面和脚本之间进行数据交互时&#xff0c;浏览器会默认允许操作&#xff0c;而不会造成跨站脚本攻击&#x…

柑橘病害数据集(四类图像分类,没有打yolo标签)

1.文件夹分为训练集和测试集 在这个数据集中&#xff0c;有一类是新鲜柑橘&#xff0c;还有另外三种疾病&#xff0c;溃疡病、黑斑病和绿化病。 2.train文件夹 2.1.blackspot&#xff08;黑斑病&#xff09; 文件夹 206张照片 2.2.canker&#xff08;溃疡病&#xff09; 文…

发布鸿蒙的第一个java应用

1.下载和安装华为自己的app开发软件DevEco Studio HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 2.打开IDE新建工程&#xff08;当前用的IDEA 3.1.1 Release&#xff09; 选择第一个&#xff0c;其他的默认只能用(API9)版本&#xff0c;搞了半天才发现8&#xff…

PPT 遇到问题总结(修改页码统计)

PPT常见问题 1. 修改页码自动计数 1. 修改页码自动计数 点击 视图——>幻灯片母版——>下翻找到计数页直接修改——>关闭母版视图

HarmonyOS4.0系列——02、汉化插件、声明式开发范式ArkTS和类web开发范式

编辑器调整 我们在每次退出编辑器后再次打开会直接进入项目文件中&#xff0c;这样在新建项目用起来很是不方便&#xff0c;所以这里跟着设置一下就好 这样下次进入就不会直接跳转到当时的文件项目中&#xff01;&#xff01; 关于汉化 settings → plugins → installe…

时间序列预测实战(十九)魔改Informer模型进行滚动长期预测(科研版本)

论文地址->Informer论文地址PDF点击即可阅读 代码地址-> 论文官方代码地址点击即可跳转下载GIthub链接 个人魔改版本地址-> 文章末尾 一、本文介绍 在之前的文章中我们已经讲过Informer模型了&#xff0c;但是呢官方的预测功能开发的很简陋只能设定固定长度去预测未…