如何高效地将三角矩阵存储在内存中?

2023-11-21

我想存储一个下三角矩阵在内存中,而不存储所有的零。 我实现它的方法是分配空间i + 1上的元素i扔。 然而,我对 C 中的动态内存分配很陌生,我的第一次分配似乎出了问题。

int main ()
{
    int i, j;
    int **mat1;
    int dim;

    scanf("%d", &dim);
    *mat1 = (int**) calloc(dim, sizeof(int*));

    for(i = 0; i < dim; i++)
    mat1[i] = (int*) calloc(i + 1, sizeof(int));

    for(i = 0; i < dim; i++)
    {
        for(j = 0; j < i + 1; j++)
        {
            scanf("%d", &mat1[i][j]);
        }
    }

    /* Print the matrix without the zeros*/
    for(i = 0; i < dim; i++)
    {
        for(j = 0; j < (i + 1); j++)
        {
            printf("%d%c", mat1[i][j], j != (dim-1) ? ' ' : '\n');
        }
    }

    return 0;
}

如果您想节省空间和分配矩阵每一行的开销,您可以通过使用单个数组的巧妙索引来实现三角矩阵。

下三角矩阵(包括对角线)具有以下属性:


Dimension   Matrix    Elements/row   Total elements
1           x . . .   1              1
2           x x . .   2              3
3           x x x .   3              6
4           x x x x   4              10
...
  

给定维度的元素总数为:

size(d) = 1 + 2 + 3 + ... + d  =  (d+1)(d/2)

如果将行连续放置在单个数组中,则可以使用上面的公式来计算矩阵内给定行和列(均从零开始)的偏移量:

index(r,c) = size(r-1) + c

上面的公式适用于下三角矩阵。您可以通过简单地反转索引来访问上矩阵,就好像它是下矩阵一样:

index((d-1)-r, (d-1)-c)

如果您担心更改阵列的方向,可以为上部阵列设计不同的偏移计算,例如:

uindex(r,c) = size(d)-size(d-r) + c-r

示例代码:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#define TRM_SIZE(dim) (((dim)*(dim+1))/2)
#define TRM_OFFSET(r,c) (TRM_SIZE((r)-1)+(c))
#define TRM_INDEX(m,r,c) ((r)<(c) ? 0 : (m)[TRM_OFFSET((r),(c))])
#define TRM_UINDEX(m,r,c,d) ((r)>(c)?0:(m)[TRM_SIZE(d)-TRM_SIZE((d)-(r))+(c)-(r)])
#define UMACRO 0


int main (void)
{
  int i, j, k, dimension;
  int *ml, *mu, *mr;

  printf ("Enter dimension: ");
  if (!scanf ("%2d", &dimension)) {
    return 1;
  }

  ml = calloc (TRM_SIZE(dimension), sizeof *ml);
  mu = calloc (TRM_SIZE(dimension), sizeof *mu);
  mr = calloc (dimension*dimension, sizeof *mr);
  if (!ml || !mu || !mr) {
    free (ml);
    free (mu);
    free (mr);
    return 2;
  }

  /* Initialization */

  srand (time (0));
  for (i = 0; i < TRM_SIZE(dimension); i++) {
    ml[i] = 100.0*rand() / RAND_MAX;
    mu[i] = 100.0*rand() / RAND_MAX;
  }

  /* Multiplication */

  for (i = 0; i < dimension; i++) {
    for (j = 0; j < dimension; j++) {
      for (k = 0; k < dimension; k++) {
        mr[i*dimension + j] +=
#if UMACRO
          TRM_INDEX(ml, i, k) *
          TRM_UINDEX(mu, k, j, dimension);
#else
          TRM_INDEX(ml, i, k) *
          TRM_INDEX(mu, dimension-1-k, dimension-1-j);
#endif
      }
    }
  }

  /* Output */

  puts ("Lower array");
  for (i = 0; i < dimension; i++) {
    for (j = 0; j < dimension; j++) {
      printf (" %2d", TRM_INDEX(ml, i, j));
    }
    putchar ('\n');
  }
  puts ("Upper array");
  for (i = 0; i < dimension; i++) {
    for (j = 0; j < dimension; j++) {
#if UMACRO
      printf (" %2d", TRM_UINDEX(mu, i, j, dimension));
#else
      printf (" %2d", TRM_INDEX(mu, dimension-1-i, dimension-1-j));
#endif
    }
    putchar ('\n');
  }
  puts ("Result");
  for (i = 0; i < dimension; i++) {
    for (j = 0; j < dimension; j++) {
      printf (" %5d", mr[i*dimension + j]);
    }
    putchar ('\n');
  }

  free (mu);
  free (ml);
  free (mr);

  return 0;
}

请注意,这是一个简单的示例。您可以扩展它以将矩阵指针包装在一个结构中,该结构还存储矩阵的类型(上三角或下三角或正方形)和维度,并编写根据矩阵类型适当操作的访问函数。

对于矩阵的任何重要用途,您可能应该使用专门研究矩阵的第三方库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何高效地将三角矩阵存储在内存中? 的相关文章

  • 如何按值删除数组中的多个项目?

    我正在尝试做一个removeAll 函数 它将删除具有该特定值 而不是索引 的数组的所有元素 当我们对循环进行任何更改时 棘手的部分就出现了 索引往往会移动 使其很难像我们想要的那样工作 并且每次更改时都重新启动循环 这在大数组上效率非常低
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 将一维数组转换为二维数组[重复]

    这个问题在这里已经有答案了 我正在开发一个程序 我必须将文本文件中的值读入一维数组 我已经成功获取该一维数组中的数字 m1 1 2 3 4 5 6 7 8 9 但我希望数组是 m1 1 2 3 4 5 6 7 8 9 您可以使用此代码 co
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new

随机推荐

  • 如何编写 bash 脚本来在进程终止时重新启动该进程?

    我有一个 python 脚本 它将检查队列并对每个项目执行操作 checkqueue py while True check queue do something 如何编写一个 bash 脚本来检查它是否正在运行 如果没有 则启动它 大致如
  • 从 NSURL 转换为 NSURLRequest 时丢失 /

    我正在我的 iPhone 应用程序中执行 HTTP Post 我发送到服务器的参数之一是 URL 问题是 当我从 NSURL 转换为 NSURLRequest 时 字符串http www slashdot org变为 http www sl
  • jquery 父容器的宽度

    如何设置 DOP ThumbnailGallery Container 以具有父容器的宽度 DOP ThumbnailGallery Container Container width Container width 我尝试了这种方式 但它
  • 将字符串数组转换为向量的最佳方法?

    正如标题所示 将字符串数组转换为向量的最佳方法是什么 Thanks 调用使用现有集合 在本例中为数组 的 Vector 构造函数来初始化自身 String strings Here Are Some Strings Vector
  • 从字符串中删除多个单词的更好方法?

    bannedWord Good Bad Ugly def RemoveBannedWords toPrint database statement toPrint for x in range 0 len database if banne
  • 基于范围的 for 循环可以在一定范围内工作

    如果我有范围 两个迭代器对 有没有一种方法可以为使用范围而不是原始数组或容器编写 for every 循环 像这样的东西 auto rng std equal range v begin v end 1984 for const auto
  • 如何阻止 jQuery UI 选项卡内的 SWF 重新加载

    我在 jQuery UI 选项卡中有一个 SWF 影片 我遇到的问题是 每次我从该选项卡单击到另一个选项卡 然后单击返回时 SWF 都会重新加载 我可以检查 DOM 并看到当我单击离开时包含 SWF 的 div 仍然在 DOM 中 所以我不
  • 如何以相对方式使用 setwd?

    我们的团队在 git 存储库中使用 R 脚本 这些脚本在 Mac 和 Windows 有时还有 Linux 机器上的多人之间共享 这往往会导致脚本顶部出现一堆非常烦人的行 如下所示 path lt C data work project a
  • 本地安装的 TTF 会覆盖 Google 字体

    我正在使用 Google Fonts 中的 Ubuntu 字体 我的样式表 body font family ubuntu arial 它可以工作 但如果安装同名的字体 Ubuntu 它会覆盖 Google Fonts 中的字体 是否可以强
  • 何时使用 MySQLdb 关闭游标

    我正在构建一个 WSGI Web 应用程序 并且有一个 MySQL 数据库 我正在使用 MySQLdb 它提供用于执行语句和获取结果的游标 获取和关闭游标的标准做法是什么 特别是 我的光标应该持续多长时间 我应该为每笔交易获取一个新的游标吗
  • XNA Alpha 混合使纹理的一部分透明

    我想做的是在 XNA 中使用 alpha 混合来使绘制的纹理的一部分透明 例如 我将屏幕清除为某种颜色 比如说蓝色 然后我画一个红色的纹理 最后 我绘制一个纹理 该纹理只是从中心完全透明到边缘完全黑色的径向渐变 我想要的是之前绘制的红色纹理
  • 如何在 iOS 上使用 Google Drive API 处理电子表格

    我正在尝试编写一个 iPhone 应用程序 将其数据库存储在 Google 电子表格中 我按照 DrEdit 的例子here它使用 Drive API 将纯文本文件读取 写入 Google Drive 我正在尝试修改示例应用程序以使用电子表
  • 编程理论:解决迷宫

    解决迷宫问题有哪些可能的方法 我有两个想法 但我认为它们不是很优雅 基地情况 我们有一个矩阵 这个矩阵中的元素以一种代表迷宫的方式排序 有一个入口 一个出口 我的第一个想法是派一个机器人穿过迷宫 跟随一侧 直到走出迷宫 我认为这是一个非常缓
  • 除非授予权限后重新启动应用程序,否则无法写入外部存储

    即使在运行时授予 WRITE EXTERNAL STORAGE 之后 应用程序也无法在 Android 6 0 上写入外部存储 我正在模拟器上进行测试 除非应用程序被终止并重新启动 AndroidManifest xml 中的片段
  • 在 Kotlin 中,当枚举类实现接口时,如何解决继承声明冲突?

    我定义了一个实现 Neo4j 的枚举类RelationshipType enum class MyRelationshipType RelationshipType 我收到以下错误 Inherited platform declaratio
  • Jenkins Pipeline emailext $class 参数用于recipientProviders

    我一直在尝试理解下面的管道常规代码 emailext subject STARTED Job env JOB NAME env BUILD NUMBER body p STARTED Job env JOB NAME env BUILD N
  • POST 多个参数到 WCF 服务

    我想了解 WCF 所以我的问题可能很愚蠢 我相信我对 GET 操作已经有了深入的了解 我现在正在从事一些 POST 操作 我的问题是 我可以使用 WebInvoke 编写接受多个参数的 WCF 服务操作吗 或者 当我发布数据时 它只会接受单
  • 获取 Collection 对象上项目的键

    环境是我推入 Collection 的成员是无名的 无法识别的 为了避免糟糕的抽象 请不要惊慌 成员实际上是其他 Collection 实例 为了能够进行快速搜索 我为每个新成员创建一个有意义的哈希名称 并将其作为 最顶层 集合的 Add
  • PHP函数生成v4 UUID

    因此 我一直在进行一些挖掘 并尝试拼凑出一个在 PHP 中生成有效 v4 UUID 的函数 这是我能到达的最接近的一次 我对十六进制 十进制 二进制 PHP 位运算符等方面的知识几乎不存在 此函数生成一个有效的 v4 UUID 直到一个区域
  • 如何高效地将三角矩阵存储在内存中?

    我想存储一个下三角矩阵在内存中 而不存储所有的零 我实现它的方法是分配空间i 1上的元素i扔 然而 我对 C 中的动态内存分配很陌生 我的第一次分配似乎出了问题 int main int i j int mat1 int dim scanf