注:着急想要源代码的请自取哦,项目地址在https://github.com/littlewith/Matrix-transpose
个人主页:https://littlewith.top
博客:https://littlewith.github.io
程序设计:
1.1 课程设计课题:
利用稀疏矩阵的三元组表示法求其转置矩阵,并输出转置后的矩阵和其三元组的表示。(限一人完成)
1.2 课程设计程序需求分析:
(1)需要有菜单引导用户进行操作,用户可以根据菜单的显示选择相应的操作。
(2)用户可以根据自己的需求输入任意一个稀疏矩阵,输入的矩阵通过程序转换为三元组的存储方式。
(3)在程序进行处理时,可以使用快速矩阵转置的算法对矩阵进行转置,也可以使用普通的转置算法进行
转置。
(4)可以输出矩阵,包括查看转置前的矩阵、转置后的矩阵。
2.1 存储结构设计
稀疏稀疏矩阵是指在矩阵中含 0 元素占比特别多的矩阵,存储稀疏矩阵一般采用三元组来进行表示。可以采用两种数据结构来进行存储。一种是结构体变量,主要用于存储单个非零元素的值,包含该非零元素所在的行数、列数、以及该元素的值。令定义一个新的结构体以该结构体数组为成员,用于创建整个矩阵的数据,包含了该矩阵的行数、列数、非零元素的个数,从而能够将一个稀疏矩阵内的数据统一成一个整体。
2.2.1 菜单模块:int Menu();
这个模块的主要功能是进行程序的界面进行打印和提示。通过输出相应的字符来提醒用户来进行相应的操作,同时也能对用户的错误输入进行相应的提示,指导用户进行重新输入。该函数会根据用户的选择来返回相应的返回值,以便于控制器中进行相应的操作。
2.2.2 初始化稀疏矩阵模块:int init(Triple s);
这个模块的主要功能是对程序中的矩阵进行初始化操作,用于将分配好内存的矩阵中的行和列均初始化为 0,从而便于进行下一步赋值等操作。
2.2.3 创建矩阵模块:int create(TSmatrix b);
这个模块的主要功能是进行矩阵的录入操作,让用户按照三元组的存储方式实现矩阵的录入操作。被录入的矩阵数据会被存入到内存中进行等待相应的处理。
2.2.4 展示矩阵模块:void display(TSmatrix b);
这个模块的主要功能是打印当前内存中存储的矩阵,虽然矩阵是按照三元组的方式存储的,但是这个函数会按照一般的规则将矩阵完整地打印出来,以便于用户更直观地查看到矩阵的内容。
2.2.5 转置方式选择模块:int chooseMethods();
这个模块的主要功能是引导用户选择相应的转置方式。程序内置了两种转置的方式,分别是快速转置方式和普通转置方式,用户根据控制台上输出的提示信息选择对应的转置方式对矩阵进行操作。该函数会根据用户所选的选项返回相应的值,以便于在控制器中进行操作。
2.2.6 普通方式转置模块:void TransposetMatrix(TSmatrix a,TSmatrix b);
这个模块的主要功能是用于以普通的方式来转置存储在内存中的矩阵,并且将转置后的矩阵以 b 的指针进行返回。
2.2.7 快速方式转置模块:void fastTrans(TSmatrix a,TSmatrix*b);
这个模块主要功能是用于以快速转置的方式来转置存储在内存中的矩阵,并且将转置后的矩阵以 b 的指针进行返回。
2.2.8 控制器(主函数):
主函数的功能是对各个模块的作用进行协调,负责初始化矩阵,分配内存,触发相应的功能等,是程序的主要运行入点。
程序源代码如下所示:
#include<stdio.h>
#include<Windows.h>
#define MAXSIZE 1000
typedef int elemType;
//定义单个非零元素类型
typedef struct {
int row;//定义行下标
int col;//定义列下标
elemType elem;//定义具体的值
} Triple;
//定义矩阵数组
typedef struct {
Triple data[MAXSIZE + 1];//分配内存,最大为MAXSIZE
int m;//行数
int n;//列数
int len;//非零元素个数
} TSmatrix;
int init(Triple* s) {
s->row = s->col = 0;
}
int create(TSmatrix* b) {
int i;
//先执行清零操作,删除原来矩阵中存储的值
for (i = 0; i < MAXSIZE; i++) {
b->data[i].elem = 0;
}
printf("请输入行数列数以及非零元素个数: ");
scanf("%d%d%d", &b->m, &b->n, &b->len);
for (i = 1; i <= b->len; i++) {
printf("请依次输入元素的行、列、值: ");
scanf("%d%d%d", &b->data[i].row, &b->data[i].col, &b->data[i].elem);
}
system("cls");
printf("\t\t\n\t\t矩阵录入成功了捏!!");
getchar();
getchar();
}
//C语言普通转置算法实现
void TransposetMatrix(TSmatrix a, TSmatrix* b)
{
int i, j, k;
//先执行清零操作,删除原来矩阵中存储的值
for (i = 0; i < MAXSIZE; i++) {
b->data[i].elem = 0;
}
b->m = a.n;
b->n = a.m;
b->len = a.len;
if (b->len <= 0)
printf("矩阵是空的!\n");
else
if (b->len > MAXSIZE)
printf("矩阵错误,超出最大存储空间!\n");
else
{
j = 1;
for (k = 1; k <= a.n; k++)
for (i = 1; i <= a.len; i++)
if (a.data[i].col == k)
{
b->data[j].row = a.data[i].col;//交换行和列
b->data[j].col = a.data[i].row;//交换行和列
b->data[j].elem = a.data[i].elem;//值不变,直接赋值就行
j++;
}
}
}
//C语言快速转置算法实现
void fastTrans(TSmatrix a, TSmatrix* b)
{
int i;
//先执行清零操作,删除原来矩阵中存储的值
for (i = 0; i < MAXSIZE; i++) {
b->data[i].elem = 0;
}
int col, t, p, q;
int num[MAXSIZE], position[MAXSIZE];
b->len = a.len;
b->n = a.m;
b->m = a.n;
if (b->len <= 0)
printf("矩阵是空的!");
else if (b->len > MAXSIZE)
printf("数组错误,超过最大存储容量");
else {
for (col = 1; col <= a.n; col++)
num[col] = 0;
for (t = 1; t <= a.len; t++)
num[a.data[t].col]++;
position[1] = 1;
for (col = 2; col < a.n; col++)
position[col] = position[col - 1] + num[col - 1];
for (p = 1; p <= a.len; p++)
{
col = a.data[p].col;
q = position[col];
b->data[q].row = a.data[p].col;//这里访问冲突
b->data[q].col = a.data[p].row;
b->data[q].elem = a.data[p].elem;
position[col]++;
}
}
}
void display(TSmatrix* b)
{
printf("嘀嘀嘀......这个矩阵当前是这样的奥!!");
putchar('\n');
int i, j, k;
for (i = 1; i <= b->m; i++) {
for (j = 1; j <= b->n; j++)
{
for (k = 1; k <= b->len; k++)
{
if (b->data[k].row == i && b->data[k].col == j) {//行匹配,列也匹配的时候
printf("%5d", b->data[k].elem);
break;
}
}
if (k > b->len)
printf("%5d", 0);
if (j == b->n)
{
putchar('\n');
putchar('\n');
}
}
}
printf("\n\t按任意键返回!");
getchar();
getchar();
}
int chooseMethods() {
while (1) {
printf("\t\t请选择你要对矩阵转置的方式:\n");
printf("\t\t\t1.使用普通转置的方式对矩阵进行转置\n");
printf("\t\t\t2.使用快速转置的方式对矩阵进行转置\n");
printf("\t\t\t3.返回上一级\n");
printf("\t\t\t4.现在退出程序\n");
printf("\t请输入你的选择: ");
char choose;
scanf("%c", &choose);
switch (choose)
{
case '1':return 1; break;
case '2':return 2; break;
case '3':return 3; break;
case '4':return 4; break;//退出信息
default:
{
system("cls");
printf("\t\t\t你你你........你好好看看选项奥!\n");
printf("\t\t\t输错了...........\n");
printf("\t\t\t重新输一遍吧\n");
}
getchar();
getchar();
system("cls");
continue;
}
}
}
int menu() {//用户界面啊
while (1) {
printf("========================================================================================================\n");
printf("\t\t\t\t欢迎使用矩阵转置小工具!\t\t\t\n");
putchar('\n');
printf("\t\t\t1.输入矩阵\t\t2.执行转置操作\n");
putchar('\n');
printf("\t\t\t3.打印当前矩阵\t\t4.退出程序\n");
printf("========================================================================================================\n");
printf("\t\t请选择你的操作:\t");
char choose;
scanf("%c", &choose);
switch (choose)
{
case '1':return 1; break;
case '2':return 2; break;
case '3':return 3; break;
case '4':return 4; break;
default:
{
system("cls");
printf("\t\t\t你你你........你好好看看选项奥!\n");
printf("\t\t\t输错了...........\n");
printf("\t\t\t重新输一遍吧\n");
}
getchar();
getchar();
system("cls");
continue;
}
}
}
int main() {//主函数
Triple s;//初始化矩阵
TSmatrix a, b, c;//初始化矩阵
init(&s);
int isCreate = 0;
char nowMatrix = 'a';//初始录入的矩阵保存在a中,此时函数所有的作用对象均为a
//当前操作的矩阵.
while (1) {
system("cls");
//程序清屏
int choose = menu();
//触发函数,进入主要的菜单,即用户的主界面,接受数据的返回值交给choose,choose包含了选择的信息。
if (choose == 1) {//对选择的choose进行判断,如果choose 为1,那么就输入矩阵
system("cls");
create(&a);//调用创建的函数
isCreate = 1;//是否创建的标识变为1,表示已经创建
nowMatrix = 'a';
}
else if (choose == 2) {//如果选择的是2,先判断是否进行了创建
system("cls");
//判断当前的矩阵是否已经初始化。
if (isCreate == 0) {
putchar('\n');
printf("\t\tNoNoNo!!!矩阵还没有初始化捏!请先执行1来初始化矩阵哦!");
getchar();//停一下
getchar();
}
else
while (1) {//否则进入下一个循环菜单
getchar();
system("cls");
int choose = chooseMethods();
if (choose == 1) {//快速转置
TransposetMatrix(a, &b);
system("cls");
printf("\t\t矩阵转置成功了!");
getchar();//过滤两个回车
//system("cls");
nowMatrix = 'b';
a = b;
}
else if (choose == 2) {//普通转置
fastTrans(a, &c);
system("cls");
printf("\t\t矩阵转置成功了!");
getchar();//过滤两个回车
//system("cls");
nowMatrix = 'c';
a = c;
}
else if (choose == 3) {//返回上一级
getchar();
break;
}
else if (choose == 4) {
system("cls");
printf("\t\t程序即将退出..........");
putchar('\n');
Sleep(500);
exit(0);
}
}
}
else if (choose == 3) {
system("cls");
if (isCreate == 0) {
putchar('\n');
printf("NoNoNo!!!矩阵还没有初始化捏!请先执行1来初始化矩阵哦!");
getchar();
getchar();
}
else {
system("cls");
if (nowMatrix == 'a') {
display(&a);
}
else if (nowMatrix == 'b') {
display(&b);
}
else if (nowMatrix == 'c') {
display(&c);
}
}
}
else if (choose == 4) {
system("cls");
printf("\t\t程序即将退出..........");
putchar('\n');
Sleep(500);
exit(0);
}
}
return 0;
}