求闭包,C语言,矩阵相乘与warshall算法

矩阵相乘与沃舍尔算法
矩阵相乘
按照教科书的题目设计的程序,给定测试用例如下
(a,c),(b,d),(c,a),(d,b),(e,d)#
bc be ce da eb ec#
ab ac ae ba bc ca cb da ed#
ae ba bd cd da dc ea eb ec ee#
结果放在尾部

#include<stdio.h>

#define SIZE 5

/*输入矩阵*/
void inputMatrix(int matrix[][SIZE]);
/*打印矩阵*/
void printfMatrix(int matrix[][SIZE]);
/*沃舍尔算法,搞错了,是复杂度高的矩阵相乘算法*/
void wosher(int matrix[][SIZE]);
/*两个矩阵求布尔积,该问题都是n*n矩阵,即方阵,并把布尔积保留在result矩阵之中*/
void multiplyMatrix(int tem_matrix[][SIZE],int matrix[][SIZE],int result_matrix[][SIZE]);
/*将后一个矩阵的内容同等赋值给第一个矩阵*/
void copyMatrix(int matrix1[][SIZE],int matrix2[][SIZE]);
/*两个数组去或运算,结果保留在tem数组中*/
void disjunctionMatrix(int matrix1[][SIZE],int matrix2[][SIZE]);
/*真正的Warshall算法*/
void warshall(int matrix[][SIZE]);
int main()
{
    int matrix[SIZE][SIZE] = {0};
    inputMatrix(matrix);
    printf("W0\n");
    printfMatrix(matrix);
    //wosher(matrix);//矩阵相乘算法
    warshall(matrix);//warshall算法
    return 0;
}
/*输入矩阵*/
void inputMatrix(int matrix[][SIZE])
{
    char str;
    char x,y;           //记录字符
    int flag = 0;       //表示当前记录几个字符
    scanf("%c",&str);
    while(str != '#')
    {
        if(str >= 'a' && str <= 'e')
        {
            if(flag == 0)
            {
                flag = 1;
                x = str;
            }
            else if(flag == 1)
            {
                y = str;
                flag = 2;
            }
        }
        if(flag == 2)
        {
            matrix[x - 'a'][y - 'a'] = 1;
            flag = 0;  //将flag置零,重新计数
        }
        scanf("%c",&str);
    }
}
/*打印矩阵*/
void printfMatrix(int matrix[][SIZE])
{
    int i,j;
    for(i = 0;i < SIZE;i++)
    {
        for(j = 0;j < SIZE;j++)
            printf("%d ",matrix[i][j]);
        printf("\n");
    }
}
/*沃舍尔算法,搞错了,是复杂度高的矩阵相乘算法*/
void wosher(int matrix[][SIZE])
{
    int i;
    int tem_matrix[SIZE][SIZE];
    int result_matrix[SIZE][SIZE];
    copyMatrix(tem_matrix,matrix);      //复制原数组到临时数组
    for(i = 0; i< SIZE;i++)
    {
        multiplyMatrix(tem_matrix,matrix,result_matrix);  //进行布尔积运算,结果保留在临时数组之中
        disjunctionMatrix(tem_matrix,result_matrix);
        printf("\nW%d\n",i + 1);
        printfMatrix(tem_matrix);
    }
}
/*两个矩阵求布尔积,该问题都是n*n矩阵,即方阵,并把布尔积保留在前一个矩阵之中*/
void multiplyMatrix(int tem_matrix[][SIZE],int matrix[][SIZE],int result_matrix[][SIZE])
{
    //int result_matrix[SIZE][SIZE] = {0};
    int i,j,k;
    for(i = 0;i < SIZE;i++)
    {
        for(j = 0;j < SIZE;j++)
        {
            result_matrix[i][j] = 0; //初始化为0
            for(k = 0;k < SIZE;k++)
            {
                result_matrix[i][j] += tem_matrix[i][k] * matrix[k][j];
            }
            if(result_matrix[i][j] > 0) result_matrix[i][j] = 1;  //大于等于2的赋值为1
        }
    }
    //copyMatrix(tem_matrix,result_matrix);
}
/*将后一个矩阵的内容同等赋值给第一个矩阵*/
void copyMatrix(int matrix1[][SIZE],int matrix2[][SIZE])
{
    int i,j;
    for(i = 0;i < SIZE;i++)
        for(j = 0;j < SIZE;j++)
            matrix1[i][j] = matrix2[i][j];
}
/*两个数组去或运算,结果保留在tem数组中*/
void disjunctionMatrix(int matrix1[][SIZE],int matrix2[][SIZE])
{
    int i,j;
    for(i = 0;i < SIZE;i++)
    {
        for(j = 0;j < SIZE;j++)
        {
            matrix1[i][j] = (matrix1[i][j] || matrix2[i][j]);
        }
    }
}
/*真正的Warshall算法*/
void warshall(int matrix[][SIZE])
{
    int i,j,k;
    for(i = 0;i < SIZE;i++)//列
    {
        for(j = 0;j < SIZE;j++)//行
        {
            if(matrix[j][i] == 1)  //一列一列找,先列后行,ji + ik -->jk
            {
                for(k = 0;k < SIZE;k++)    //遍历第i行
                {
                    matrix[j][k] = matrix[j][k] + matrix[i][k];
                    if(matrix[j][k] > 0) matrix[j][k] = 1;          //防止大于等于1的数字出现
                }
            }
            
            /*if及里面的语句可以换成如下的语句*/
//            for(k = 0;k < SIZE;k++)
//            {
//                matrix[j][k] = matrix[j][k] | (matrix[j][i] & matrix[i][k]);//通过matrix[j][i] 与 matrix[i][k]找到matrix[j][k]的逻辑值
//            }
        }
        /*以第一个节点为中间点的路径已经寻找完毕*/
            printf("\nW%d\n",i + 1);
            printfMatrix(matrix);
    }
}

结果依次对应上面四个样例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值