找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 927|回复: 0

【C】对矩阵做广义笛卡尔积运算

[复制链接]
发表于 2022-5-18 21:20:40 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 usr 于 2022-5-18 21:30 编辑

对关系做笛卡尔积是DBMS中一个比较重要的操作。如果有两个关系A和B,A的列数是m,B的列数是n;
A的行数是x,B的行数是y。则,A*B的列数是m+n,行数是x*y。因为关系可以使用矩阵表示。
以下的代码显示了对两个关系矩阵生成笛卡尔积的过程。注意本程序需要StoneValley库的支持。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "./StoneValley/src/svstring.h"

  4. P_MATRIX CreateCartesianProduct(P_MATRIX pma, P_MATRIX pmb, size_t size)
  5. {
  6.         size_t m, n;
  7.         P_MATRIX pmr = strCreateMatrix(m = pma->ln * pmb->ln, n = pma->col + pma->col, size);
  8.         if (NULL != pmr)
  9.         {
  10.                 REGISTER size_t i, x, y;
  11.                 for (i = 0, x = 0, y = 0; i < m; ++i)
  12.                 {
  13.                         /* Fill tuples of pma to pmr. */
  14.                         memcpy(strGetValueMatrix(NULL, pmr, i, 0, size), strGetValueMatrix(NULL, pma, x, 0, size), size * pma->col);
  15.                         /* Fill tuples of pmb to pmr. */
  16.                         memcpy(strGetValueMatrix(NULL, pmr, i, pma->col, size), strGetValueMatrix(NULL, pmb, y, 0, size), size * pmb->col);
  17.                         if (0 == (i + 1) % pmb->ln)
  18.                                 ++x;
  19.                         if (++y == pmb->ln)
  20.                                 y = 0;
  21.                 }
  22.         }
  23.         return pmr;
  24. }

  25. int cbftvs(void * pitem, size_t size)
  26. {
  27.         static i = 1;
  28.         printf("%s ", (char *)pitem);
  29.         if (0 == i % size)
  30.                 printf("\n");
  31.         ++i;
  32.         return CBF_CONTINUE;
  33. }

  34. int main()
  35. {
  36.         P_MATRIX pmb = NULL, pmc = NULL;
  37.         P_MATRIX pma = strCreateMatrix(3, 3, sizeof(char *));
  38.         strSetValueMatrix(pma, 0, 0, "a1", sizeof(char *));
  39.         strSetValueMatrix(pma, 0, 1, "b1", sizeof(char *));
  40.         strSetValueMatrix(pma, 0, 2, "c1", sizeof(char *));

  41.         strSetValueMatrix(pma, 1, 0, "a1", sizeof(char *));
  42.         strSetValueMatrix(pma, 1, 1, "b2", sizeof(char *));
  43.         strSetValueMatrix(pma, 1, 2, "c2", sizeof(char *));

  44.         strSetValueMatrix(pma, 2, 0, "a2", sizeof(char *));
  45.         strSetValueMatrix(pma, 2, 1, "b2", sizeof(char *));
  46.         strSetValueMatrix(pma, 2, 2, "c1", sizeof(char *));

  47.         pmb = strCreateMatrix(3, 3, sizeof(char *));
  48.         strSetValueMatrix(pmb, 0, 0, "a1", sizeof(char *));
  49.         strSetValueMatrix(pmb, 0, 1, "b2", sizeof(char *));
  50.         strSetValueMatrix(pmb, 0, 2, "c2", sizeof(char *));

  51.         strSetValueMatrix(pmb, 1, 0, "a1", sizeof(char *));
  52.         strSetValueMatrix(pmb, 1, 1, "b3", sizeof(char *));
  53.         strSetValueMatrix(pmb, 1, 2, "c2", sizeof(char *));

  54.         strSetValueMatrix(pmb, 2, 0, "a2", sizeof(char *));
  55.         strSetValueMatrix(pmb, 2, 1, "b2", sizeof(char *));
  56.         strSetValueMatrix(pmb, 2, 2, "c1", sizeof(char *));

  57.         pmc = CreateCartesianProduct(pma, pmb, sizeof(char *));

  58.         strTraverseArrayZ(&pma->arrz, sizeof(char *), cbftvs, 3, FALSE);
  59.         printf("\n");
  60.         strTraverseArrayZ(&pmb->arrz, sizeof(char *), cbftvs, 3, FALSE);
  61.         printf("\n");

  62.         strTraverseArrayZ(&pmc->arrz, sizeof(char *), cbftvs, 6, FALSE);

  63.         strDeleteMatrix(pma);
  64.         strDeleteMatrix(pmb);
  65.         strDeleteMatrix(pmc);
  66.         return 0;
  67. }
复制代码

运行结果如下:
a1 b1 c1
a1 b2 c2 (关系A)
a2 b2 c1

a1 b2 c2
a1 b3 c2 (关系B)
a2 b2 c1

a1 b1 c1 a1 b2 c2 (笛卡尔积)
a1 b1 c1 a1 b3 c2
a1 b1 c1 a2 b2 c1
a1 b2 c2 a1 b2 c2
a1 b2 c2 a1 b3 c2
a1 b2 c2 a2 b2 c1
a2 b2 c1 a1 b2 c2
a2 b2 c1 a1 b3 c2
a2 b2 c1 a2 b2 c1
对于对关系做传统的集合运算“交并差”笔者会在日后的帖子里补上。
欢迎在本贴讨论DBMS相关知识或者笛卡尔积的优化技巧。
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-26 23:03 , Processed in 0.037559 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表