三元组矩阵的乘法(c#实现)

博客中代码都经过运行并且没有bug

//三元组数据结构表示的矩阵相乘
  class Program
  {
    //矩阵的非零元素的表示
    struct Triple
    {
      public int i, j;//该非零元素位于矩阵的行号和列号
      public int element;//该非零元素的值
    }


    //矩阵的表示
    struct TriMatrix
    {
      public Triple[] data;//存储三元组表示的矩阵的非零元素
      public int[] rPos;//各行第一个非零矩阵在data中的存储位置
      public int mu, nu, tu;//mu表示矩阵的行数,nu表示矩阵的列数,tu表示矩阵的非零元素的个数
    }

    //初始化第一个矩阵
    static TriMatrix InitTriMatrixFir()
    {
      TriMatrix s = new TriMatrix();
      s.mu = 5;
      s.nu = 5;
      s.tu = 5;
      s.data = new Triple[s.tu];

      Triple tempTriple = new Triple();
      tempTriple.i = 0;
      tempTriple.j = 0;
      tempTriple.element = 1;
      s.data[0] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 0;
      tempTriple.j = 3;
      tempTriple.element = 3;
      s.data[1] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 1;
      tempTriple.j = 4;
      tempTriple.element = 2;
      s.data[2] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 3;
      tempTriple.j = 1;
      tempTriple.element = 1;
      s.data[3] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 4;
      tempTriple.j = 0;
      tempTriple.element = 2;
      s.data[4] = tempTriple;

      s.rPos = new int[s.tu];
      s.rPos[0] = 0;
      s.rPos[1] = 2;
      s.rPos[2] = 2;
      s.rPos[3] = 3;
      s.rPos[4] = 4;

      return s;
    }

    //初始化第二个矩阵
    static TriMatrix InitTriMatrixSec()
    {
      TriMatrix t = new TriMatrix();
      t.mu = 5;
      t.nu = 5;
      t.tu = 5;
      t.data = new Triple[t.tu];

      Triple tempTriple = new Triple();
      tempTriple.i = 0;
      tempTriple.j = 0;
      tempTriple.element = 1;
      t.data[0] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 0;
      tempTriple.j = 3;
      tempTriple.element = 3;
      t.data[1] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 1;
      tempTriple.j = 4;
      tempTriple.element = 2;
      t.data[2] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 3;
      tempTriple.j = 1;
      tempTriple.element = 1;
      t.data[3] = tempTriple;

      tempTriple = new Triple();
      tempTriple.i = 4;
      tempTriple.j = 0;
      tempTriple.element = 2;
      t.data[4] = tempTriple;

      t.rPos = new int[t.tu];
      t.rPos[0] = 0;
      t.rPos[1] = 2;
      t.rPos[2] = 2;
      t.rPos[3] = 3;
      t.rPos[4] = 4;

      return t;
    }

    //矩阵的乘法
    static TriMatrix MultiplyTriMatrix(TriMatrix s,TriMatrix t)
    {
      bool isRposEmpty = true;

      int maxSize = 300;

      int mp,tp;

      TriMatrix multi = new TriMatrix();
      multi.mu = s.mu;
      multi.nu = t.nu;
      multi.tu = 0;
      multi.data = new Triple[maxSize];//因为开始无法确定新矩阵有多少个非零元素,所以直接按最大值开辟一个空间存储非零元素
      multi.rPos = new int[10];

      int[] multiRowTemp = new int[multi.nu];
      int multiRowTempT = 0;

      for (int i = 0; i < s.mu; i++)
      {
        for (int multiRowTempcol = 0; multiRowTempcol < multiRowTemp.Length; multiRowTempcol++)
        {
          multiRowTemp[multiRowTempcol] = 0;
        }


        //设置multi中的rPos数组
        multi.rPos[i] = multi.tu;

        if (i < s.mu - 1)
        {//mp用来存储当前行的最后一个非零元素的下一元素的位置
          mp = s.rPos[i+1];
        }
        else
        {
          mp = s.mu;
        }
        

        for (int j = s.rPos[i]; j < mp; j++)
        {
          if (i > 0 && j == s.rPos[i-1])
          {
            break;
          }

          int tRowTemp = s.data[j].j;
          if (tRowTemp < t.mu-1)
          {//tp用来存储当前行的最后一个非零元素的下一个元素的位置
            tp = t.rPos[tRowTemp+1];
          }
          else
          {
            tp = t.mu;
          }

          for (int q = t.rPos[tRowTemp]; q < tp; q++)
          {
            if (tRowTemp > 0 && tRowTemp == t.rPos[tRowTemp - 1])
            {
              break;
            }

            multiRowTempT = t.data[q].j;//存储当前计算值需要放在临时变量multiRowTemp中的位置
            multiRowTemp[multiRowTempT] += s.data[j].element * t.data[q].element;
          }
        }

        for (int col = 0; col < multi.nu; col++)
        {
          if (multiRowTemp[col] != 0)
          {
            if (i != 0)
            {
              isRposEmpty = false;
            }
            
            multi.data[multi.tu].i = i;
            multi.data[multi.tu].j = col;
            multi.data[multi.tu].element = multiRowTemp[col];


            multi.tu++;
          }
        }

        if (!isRposEmpty && i != 0)
        {
          multi.rPos[i]++;
          isRposEmpty = true;
        }

      }

      return multi;
    }

    static void Main(string[] args)
    {
      TriMatrix s = InitTriMatrixFir();
      TriMatrix t = InitTriMatrixSec();
      TriMatrix multi = MultiplyTriMatrix(s,t);


      int sIndex = 0;

      for (int i = 0; i < s.mu; i++)
      {
        for (int j = 0; j < s.nu; j++)
        {
          if (sIndex < s.tu && s.data[sIndex].i == i && s.data[sIndex].j == j)
          {
            Console.Write(s.data[sIndex].element + " ");
            sIndex++;
          }
          else
          {
            Console.Write("0 ");
          }
        }
        Console.WriteLine();
      }

      Console.WriteLine();

      for (int i = 0; i < s.rPos.Length; i++)
      {
        Console.Write(s.rPos[i]+" ");
      }

      int tIndex = 0;
      for (int i = 0; i < t.mu; i++)
      {
        for (int j = 0; j < t.nu; j++)
        {
          if (tIndex < t.tu && t.data[tIndex].i == i && t.data[tIndex].j == j)
          {
            Console.Write(t.data[tIndex].element + " ");
            tIndex++;
          }
          else
          {
            Console.Write("0 ");
          }
        }
        Console.WriteLine();
      }
      
      Console.WriteLine();

      for (int i = 0; i < t.rPos.Length; i++)
      {
        Console.Write(t.rPos[i] + " ");
      }

      int multiIndex = 0;

      Console.WriteLine();
      Console.WriteLine();

      for (int i = 0; i < multi.mu; i++)
      {
        for (int j = 0; j < multi.nu; j++)
        {
          if (multiIndex < multi.tu && multi.data[multiIndex].i == i && multi.data[multiIndex].j == j)
          {
            Console.Write(multi.data[multiIndex].element + " ");
            multiIndex++;
          }
          else
          {
            Console.Write("0 ");
          }
        }
        Console.WriteLine();
      }

      Console.WriteLine();

      for (int i = 0; i < multi.rPos.Length; i++)
      {
        Console.Write(multi.rPos[i] + " ");
      }

      Console.ReadKey();
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值