• 稀疏矩阵的一些运算C实现(转)


    #include <iostream>
    #include <iomanip>
    using namespace std;


    const int MAXSIZE = 100; //定义非零元素的最多个数
    const int MAXROW = 10; //定义数组行数的最大值
    const int SIZENUM = 10;


    typedef struct //定义三元组元素
    {
    int r, c; //矩阵的行号和列号
    int v; //矩阵元素值
    }Triple;


    typedef struct //定义普通三元组对象
    {
    Triple data[MAXSIZE+1];
    int rows, cols, nzeroNums; //行数、列数、非零元素个数
    }TSMatrix;


    typedef struct //定义行逻辑链接的顺序表
    {
    Triple data[MAXSIZE+2]; //非0元三元组表
    int rpos[MAXROW+1]; //各行第一个非零元素的位置表
    int rows, cols, nzeroNums; //行数、列数、非零元素个数
    }RLSMatrix;


    //输入三元组矩阵
    template <class T>
    bool InputTSMatrix(T &M, int y)
    {
    cout << "输入矩阵的行数、列数和非零元素个数: ";
    cin >> M.rows >> M.cols >> M.nzeroNums;
    cout << "请输入非零元素对应的行号、列号和相应的元素值: " << endl;
    for (int i = 1; i <= M.nzeroNums; i++)
    {
    cin >> M.data[i].r >> M.data[i].c >> M.data[i].v;
    }
    return true;
    }


    //输出矩阵,按标准格式输出
    template <class T>
    bool OutputSMatrix(T M)
    {
    int i, j, k = 1;
    for (i = 0; i < M.rows; i++)
    {
    for (j = 0; j < M.cols; j++)
    {
    if ((M.data[k].r-1) == i && (M.data[k].c-1) == j)
    {
    cout << setw(4) << M.data[k].v;
    k++;
    }
    else
    cout << setw(4) << "0";
    }//end_j
    cout << endl;
    }//end_i
    return true;
    }


    //求稀疏矩阵的转置
    int TranSMatrix()
    {
    TSMatrix M, T;
    InputTSMatrix(M, 0);
    int col, p, q = 1;
    T.rows = M.cols;
    T.cols = M.rows;
    T.nzeroNums = M.nzeroNums;
    if (T.nzeroNums)
    {
    for (col = 1; col <= M.cols; col++)
    {
    for (p = 1; p <= M.nzeroNums; p++)
    {
    if (M.data[p].c == col)
    {
    T.data[q].r = M.data[p].c;
    T.data[q].c = M.data[p].r;
    T.data[q].v = M.data[p].v;
    ++q;
    }
    }//end_p
    }//end_col
    }//end_if
    cout << "运用普通转置算法, 输入矩阵的转置矩阵为: " << endl;
    OutputSMatrix(T);
    return 1;
    }


    //稀疏矩阵的快速转置
    int FastTranMat()
    {
    TSMatrix M, T;
    int num[MAXROW+1]; //表示矩阵M中第col列非零元素的个数
    int cpot[MAXROW+1]; //表示矩阵M中第col列第一个非0元素在b.data中的位置
    int p, q, col, t;
    InputTSMatrix(M, 0); //输入稀疏矩阵
    T.rows = M.cols;
    T.cols = M.rows;
    T.nzeroNums = M.nzeroNums;
    if (T.nzeroNums)
    {
    for (col = 1; col <= M.cols; col++)//M中各列元素初始化
    {
    num[col] = 0;
    }
    for (t = 1; t <= M.nzeroNums; t++)
    {
    ++num[M.data[t].c]; //求M中每一列非零元个数
    }
    //求第col列第一个非零元在b.data中的序号
    cpot[1] = 1;
    for (col = 2; col <= M.cols; col++)
    {
    cpot[col] = cpot[col-1] + num[col-1];
    }
    for (p = 1; p <= M.nzeroNums; p++)
    {
    col = M.data[p].c; //稀疏矩阵M中每个元素对应的列号
    q = cpot[col]; //稀疏矩阵M中第一个非零元素位置
    T.data[q].r = M.data[p].c;
    T.data[q].c = M.data[p].r;
    T.data[q].v = M.data[p].v;
    ++cpot[col];
    }//end_for
    }//end_if
    cout << "运用快速算法,输入矩阵的转置为: " << endl;
    OutputSMatrix(T);
    return 1;
    }


    //求取稀疏矩阵每一行非零元个数
    bool Count(RLSMatrix &M)
    {
    int row, p;
    int num[MAXROW+1];
    for (row = 1; row <= M.rows; row++)
    {
    num[row] = 0; //清零
    }
    for (p = 1; p <= M.nzeroNums; p++)
    {
    ++num[M.data[p].r]; //统计M每一行非零元个数
    }
    M.rpos[1] = 1;
    //M中每一行非零元的起始位置
    for (row = 2; row <= M.rows; row++)
    {
    M.rpos[row] = M.rpos[row-1] + num[row-1];
    }
    return true;
    }


    //两个稀疏矩阵的乘法
    bool MultSMatrix()
    {
    RLSMatrix M, N, Q; //构建三个带链接信息的三元组表示的数组
    InputTSMatrix(M, 1); //用普通三元组形式输入数组
    InputTSMatrix(N, 1);
    Count(M);
    Count(N);
    if (M.cols != N.rows)
    {
    cout << "Error!";
    return false;
    }
    //Q的初始化
    Q.rows = M.rows;
    Q.cols = N.cols;
    Q.nzeroNums = 0;
    int mrow, nrow, p, q, t, tp, qcol;
    int ctemp[MAXROW+1]; //辅助数组
    //如果Q是非零矩阵
    if (M.nzeroNums * N.nzeroNums)
    {
    for (mrow = 1; mrow <= M.rows; mrow++)
    {
    //当前行各元素累加器清零
    for (int x = 1; x <= N.cols; x++)
    {
    ctemp[x] = 0;
    }//end_x
    //当前行的首个非零元素在三元组中的位置为此行前所有非0元素加1
    Q.rpos[mrow] = Q.nzeroNums + 1;
    if (mrow < M.rows)
    {
    tp = M.rpos[mrow+1];
    }
    else
    tp = M.nzeroNums + 1;
    for (p = M.rpos[mrow]; p < tp; p++) //对当前行的每个非零元素操作
    {
    nrow = M.data[p].c; //在N中找到与M操作元素的c值相等的行值r
    if (nrow < N.rows)
    {
    t = N.rpos[nrow+1];
    }
    else
    t = N.nzeroNums + 1;
    //对找出的行的每个非零元素进行操作
    for (q = N.rpos[nrow]; q < t; q++)
    {
    qcol = N.data[q].c;
    //将乘得到的对应值放在相应元素的累加器里面
    ctemp[qcol] += M.data[p].v * N.data[q].v;
    }
    }//p_end_for

    //对已经求出的累加器中的值压缩到Q中
    for (qcol = 1; qcol <= Q.cols; qcol++)
    {
    if (ctemp[qcol])
    {
    if (++Q.nzeroNums > MAXSIZE)
    {
    cout << "Error!" << endl;
    return 0;
    }
    Q.data[Q.nzeroNums].r = mrow;
    Q.data[Q.nzeroNums].c = qcol;
    Q.data[Q.nzeroNums].v = ctemp[qcol];
    }
    }//qcol_end_for
    }//arow_end_for
    }//end_if
    cout << "两个稀疏矩阵相乘的结果为: ";
    OutputSMatrix(Q);
    return 1;
    }


    //两个稀疏矩阵的加法
    int AddMatrix()
    {
    TSMatrix A, B, C;
    int i = 1, j = 1, k = 1; //i, j, k分别用以保存A、B、C非零元素个数
    int value = 0;
    InputTSMatrix(A, 0);
    InputTSMatrix(B, 0);
    if (A.rows != B.rows || A.cols != B.cols)
    {
    cout << "两个稀疏矩阵的大小不等,不能相加!" << endl;
    return 0;
    }
    if (A.rows == B.rows && A.cols == B.cols)
    {
    while (i <= A.nzeroNums && j <= B.nzeroNums)
    {
    if (A.data[i].r == B.data[j].r)
    {
    if (A.data[i].c < B.data[j].c)
    {
    C.data[k].r = A.data[i].r;
    C.data[k].c = A.data[i].c;
    C.data[k].v = A.data[i].v;
    k++;
    i++;
    }
    else if (A.data[i].c > B.data[j].c)
    {
    C.data[k].r = B.data[j].r;
    C.data[k].c = B.data[j].c;
    C.data[k].v = B.data[j].v;
    k++;
    j++;
    }
    else
    {
    value = A.data[i].v + B.data[j].v;
    if (value != 0)
    {
    C.data[k].r = A.data[i].r;
    C.data[k].c = A.data[i].c;
    C.data[k].v = value;
    k++;
    }
    i++;
    j++;
    }
    }//end_if
    else if (A.data[i].r < B.data[j].r)
    {
    C.data[k].r = A.data[i].r;
    C.data[k].c = A.data[i].c;
    C.data[k].v = A.data[i].v;
    k++;
    i++;
    }
    else
    {
    C.data[k].r = B.data[j].r;
    C.data[k].c = B.data[j].c;
    C.data[k].v = B.data[j].v;
    k++;
    j++;
    }
    //把剩余部分元素存入C中
    if (i > A.nzeroNums && j <= B.nzeroNums)
    {
    for (; j <= B.nzeroNums; j++)
    {
    C.data[k].r = B.data[j].r;
    C.data[k].c = B.data[j].c;
    C.data[k].v = B.data[j].v;
    k++;
    }
    }
    if (i <= A.nzeroNums && j > B.nzeroNums)
    {
    for (; i <= A.nzeroNums; i++)
    {
    C.data[k].r = A.data[i].r;
    C.data[k].c = A.data[i].c;
    C.data[k].v = A.data[i].v;
    k++;
    }
    }
    }//end_while
    C.rows = A.rows;
    C.cols = A.cols;
    C.nzeroNums = k-1;
    cout << "输出两个稀疏矩阵的和: " << endl;
    OutputSMatrix(C);
    return 1;
    }//end_if
    else
    return 0;
    }


    //两个稀疏矩阵的减法
    int SubMatrix()
    {
    TSMatrix A, B, C;
    int m = 1, n = 1, k = 1, temp;
    InputTSMatrix(A, 0);
    InputTSMatrix(B, 0);
    C.rows = A.rows;
    C.cols = A.cols;
    C.nzeroNums = 0;
    if (A.rows == B.rows && A.cols == B.cols)
    {
    while (m <= A.nzeroNums && n <= B.nzeroNums)
    {
    if (A.data[m].r == B.data[n].r)
    {
    if (A.data[m].c == B.data[n].c)
    {
    temp = A.data[m].v - B.data[n].v;
    if (temp != 0)
    {
    C.data[k].r = A.data[m].r;
    C.data[k].c = A.data[m].c;
    C.data[k].v = temp;
    k++;
    }
    m++;
    n++;
    }
    else if (A.data[m].c < B.data[n].c)
    {
    C.data[k].r = A.data[m].r;
    C.data[k].c = A.data[m].c;
    C.data[k].v = A.data[m].v;
    k++;
    m++;
    }
    else
    {
    C.data[k].r = B.data[n].r;
    C.data[k].c = B.data[n].c;
    C.data[k].v = -B.data[n].v;
    k++;
    n++;
    }
    }
    else if (A.data[m].r < B.data[n].r)
    {
    C.data[k].r = A.data[m].r;
    C.data[k].c = A.data[m].c;;
    C.data[k].v = A.data[m].v;
    k++;
    m++;
    }
    else
    {
    C.data[k].r = B.data[n].r;
    C.data[k].c = B.data[n].c;
    C.data[k].v = -B.data[n].v;
    k++;
    n++;
    }
    }//end_while
    if (m <= A.nzeroNums)
    {
    for (; m <= A.nzeroNums; m++)
    {
    C.data[k].r = A.data[m].r;
    C.data[k].c = A.data[m].c;
    C.data[k].v = A.data[m].v;
    k++;
    }
    }
    if (n <= B.nzeroNums)
    {
    for (; n <= B.nzeroNums; n++)
    {
    C.data[k].r = B.data[n].r;
    C.data[k].c = B.data[n].c;
    C.data[k].v = -B.data[n].v;
    k++;
    }
    }
    C.nzeroNums = k-1;
    cout << "两个稀疏矩阵的差为: ";
    OutputSMatrix(C);
    return 1;
    } //end_if
    else
    {
    cout << "两个稀疏矩阵的大小不同,不能相减! ";
    return 0;
    }
    }


    //得到矩阵元素M[i][j]的值
    int value(TSMatrix M, int i, int j)
    {
    int k;
    for (k = 1; k <= M.nzeroNums; k++)
    {
    if (M.data[k].r == i && M.data[k].c == j)
    {
    return M.data[k].v;
    }
    }
    return 0;
    }


    //矩阵乘法的算法2
    int MultMat()
    {
    TSMatrix A, B, C;
    InputTSMatrix(A, 0);
    InputTSMatrix(B, 0);
    int i, j, k, temp = 0, p = 1;
    if (A.cols != B.rows)
    {
    cout << "矩阵A的列数不等于矩阵B的行数不能相乘! ";
    return 0;
    }
    else
    {
    for (i = 1; i <= A.rows; i++)
    {
    for (j = 1; j <= B.cols; j++)
    {
    temp = 0;
    for (k = 1; k <= A.cols; k++)
    {
    temp += value(A, i, k) * value(B, k, j);
    }
    if (temp != 0)
    {
    C.data[p].r = i;
    C.data[p].c = j;
    C.data[p].v = temp;
    p++;
    }
    }
    }
    C.rows = A.rows;
    C.cols = B.cols;
    C.nzeroNums = p-1;
    OutputSMatrix(C);
    return 1;
    }
    }


    //计算矩阵的行列式, 通过递归算法来实现
    int JsMatrix(int s[][MAXROW], int n)
    {
    int i, j, k, r, total = 0;
    int b[SIZENUM][SIZENUM]; //b[N][N]用于存放在矩阵s[N][N]中元素s[0]的余之式

    if (n == 1)
    {
    total = s[0][0];
    }
    else if (n == 2)
    {
    total = s[0][0] * s[1][1] - s[0][1] * s[1][0];
    }
    else
    {
    for (i = 0; i < n; i++)
    {
    for (j = 0; j < n-1; j++)
    {
    for (k = 0; k < n-1; k++)
    {
    if (k >= i)
    {
    b[j][k] = s[j+1][k+1];
    }
    else
    {
    b[j][k] = s[j+1][k];
    }
    }//end_for_k
    }//end_for_j
    if (i % 2 == 0)
    {
    r = s[0][i] * JsMatrix(b, n-1); //递归调用
    }
    else
    {
    r = (-1) * s[0][i] * JsMatrix(b, n-1);
    }
    total += r;
    }//end_for_i
    }//end_else
    return total;
    }


    //求原矩阵个元素对应的余之式, 存放在b[n][n]中,定义为float型
    void N1Matrix(int s[][SIZENUM], float b[][SIZENUM], int n)
    {
    int i, j, k, l, m, g, a[SIZENUM][SIZENUM];
    for (i = 0; i < n; i++)
    {
    m = i;
    for (j = 0; j < n; j++)
    {
    g = j;
    for (k = 0; k < n-1; k++)
    {
    for (l = 0; l < n-1; l++)
    {
    if (k >= m && l >= g)
    {
    a[k][l] = s[k+1][l+1];
    }
    else if (k < m && l >= g)
    {
    a[k][l] = s[k][l+1];
    }
    else if (k >= m && l < g)
    {
    a[k][l] = s[k+1][l];
    }
    else
    {
    a[k][l] = s[k][l];
    }
    }//end_for_l
    }//end_for_k
    b[i][j] = JsMatrix(a, n-1);
    }//end_for_j
    }//end_for_i
    }


    //稀疏矩阵求逆
    void InverseMat()
    {
    TSMatrix M;
    InputTSMatrix(M, 0);
    int i, j, k, n = M.rows;
    float temp;
    int a[SIZENUM][SIZENUM];
    float b[SIZENUM][SIZENUM], c[SIZENUM][SIZENUM];
    for (i = 0; i < n; i++) //初始化矩阵a
    {
    for (j = 0; j < n; j++)
    {
    a[i][j] = 0;
    }
    }
    for (i = 1; i <= M.nzeroNums; i++) //给矩阵a赋值
    {
    a[M.data[i].r-1][M.data[i].c-1] = M.data[i].v;
    }
    cout << "稀疏矩阵对应的普通矩阵为: ";
    for (i = 0; i < n; i++) //打印原矩阵
    {
    for (j = 0; j < n; j++)
    {
    cout << setw(4) << a[i][j] << setw(4);
    }
    cout << endl;
    }
    k = JsMatrix(a, n);
    cout << "矩阵的行列式值: |A| = " << k << endl;
    if (k == 0)
    {
    cout << "行列式的值为0, 原矩阵无逆矩阵!" << endl;
    }
    else
    {
    N1Matrix(a, b, n); //调用函数,得到原矩阵各元素对应的余之式存放在数组b[n][n]中
    //求代数余之式
    cout << "普通矩阵各元素对应的代数余之式矩阵为: ";
    for (i = 0; i < n; i++)
    {
    for (j = 0; j < n; j++)
    {
    if ((i+j)%2 != 0 && b[i][j] != 0)
    {
    b[i][j] = -b[i][j];
    }
    cout << setw(4) << b[i][j] << setw(4);
    }
    cout << endl;
    }//end_for_i


    //对b[N][N]转置,此时b[n][n]存放的为原矩阵的伴随矩阵
    for (i = 0; i < n; i++)
    {
    for (j = i+1; j < n; j++)
    {
    temp = b[i][j];
    b[i][j] = b[j][i];
    b[j][i] = temp;
    }
    }
    cout << "伴随矩阵A*: " << endl;
    for (i = 0; i < n; i++) //打印伴随矩阵A*
    {
    for (j = 0; j < n; j++)
    {
    cout << setw(4) << b[i][j] << setw(4);
    }
    cout << endl;
    }
    for (i = 0; i < n; i++) //求逆矩阵,此时c[n][n]中存放的是原矩阵的逆矩阵
    {
    for (j = 0; j < n; j++)
    {
    c[i][j] = b[i][j]/k;
    }
    }
    cout << "逆矩阵(A*)/|A|: " << endl;
    for (i = 0; i < n; i++) //打印逆矩阵
    {
    for (j = 0; j < n; j++)
    {
    cout << setw(6) << c[i][j] << setw(6);
    }
    cout << endl;
    }
    }//end_else
    }


    int main()
    {
    char c;
    cout << setw(50) << "******欢迎使用稀疏矩阵的相关操作!******" << endl << endl;
    cout.fill('*');
    cout << setw(20) << '*';
    cout << "请选择要进行的操作";
    cout << setw(20) << '*' << endl;
    cout << setw(6) << '*' << " 1: 稀疏矩阵的普通转置算法" << endl;
    cout << setw(6) << '*' << " 2: 稀疏矩阵的快速转置算法" << endl;
    cout << setw(6) << '*' << " 3: 稀疏矩阵的乘法的快速算法" << endl;
    cout << setw(6) << '*' << " 4: 稀疏矩阵的乘法的经典算法" << endl;
    cout << setw(6) << '*' << " 5: 稀疏矩阵的加法" << endl;
    cout << setw(6) << '*' << " 6: 稀疏矩阵的减法" << endl;
    cout << setw(6) << '*' << " 7: 求稀疏矩阵的逆" << endl;
    cout << setw(6) << '*' << " 0: 退出程序" << endl;
    cout.fill(' ');
    c = getchar();
    switch(c)
    {
    case '1':
    TranSMatrix();
    break;
    case '2':
    FastTranMat();
    break;
    case '3':
    MultSMatrix();
    break;
    case '4':
    MultMat();
    break;
    case '5':
    AddMatrix();
    break;
    case '6':
    SubMatrix();
    break;
    case '7':
    InverseMat();
    break;
    case '0':
    cout << "谢谢使用! 再见!" << endl;
    break;
    default:
    cout << "错误命令!" << endl << endl;
    break;
    }
    return 0;
    }

  • 相关阅读:
    网页简单布局之结构与表现原则(HTML/CSS)
    浅谈搜索引擎SEO(HTML/CSS)
    Vue小案例(一)
    vue2.0中的计算属性
    Vue.js双向绑定原理
    Vue实例对象的数据选项(火柴)
    基于Vue的WebApp项目开发(六)
    基于Vue的WebApp项目开发(五)
    基于Vue的WebApp项目开发(四)
    基于Vue的WebApp项目开发(三)
  • 原文地址:https://www.cnblogs.com/hjj-fighting/p/12794321.html
Copyright © 2020-2023  润新知