博客中代码都经过运行并且没有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();
}
}