第1关:稀疏矩阵元素赋值

稀疏矩阵赋值子程序的编写与测试

任务描述
相关知识
稀疏矩阵的定义
给稀疏矩阵分配内存
查询一个坐标(row,col)在三元组表nodes中的位置
编程要求
测试说明
任务描述
本关任务:编写子程序,给稀疏矩阵一个单元赋值。

相关知识
为了完成本关任务,你需要掌握稀疏矩阵的三元组表示法。

稀疏矩阵的定义
typedef double TV;    //TV是矩阵元素类型double的别名
typedef struct Node {  //一个三元组结点
    int row;
    int col;
    TV  value;
}T;             //T是三元组元素Node的别名

struct SparseMatrix {
    int Rows;  //矩阵的行数
    int Cols;  //矩阵的列数
    SeqList* nodes;    //三元组表
    int maxnodes;  //元素的最大数目,规定了nodes表的最大长度
}; 

给稀疏矩阵分配内存
SparseMatrix* SM_Create(int rows, int cols, int maxnodes)
// 创建一个稀疏矩阵。
{
    SparseMatrix* A=(SparseMatrix*)malloc(sizeof(SparseMatrix));
    A->nodes=SL_Create(maxnodes); //给三元组表分配内存
    A->Rows=rows;
    A->Cols=cols;
    A->maxnodes=maxnodes;
    return A;
}

查询一个坐标(row,col)在三元组表nodes中的位置
设计这个小函数很好用,给读和写矩阵元素带来方便
int SM_Loc(SparseMatrix* A, int row, int col ){
    if(row<0||row>=A->Rows||col<0||col>=A->Cols) {
        return -2;  // -2表示坐标非法 
    }
    else {
        for (int k=0;k<SL_Length(A->nodes);k++){
            T x=SL_GetAt(A->nodes, k); //在nodes表中取元素
            if(x.row ==row && x.col==col)
                   return k ; //查到了
        }
        return -1;  //  没查到三元组元素 
    }
}

编程要求
根据提示,在右侧编辑器补充代码,实现函数
void SM_SetAt(SparseMatrix* A, int row, int col, TV x),
给一个稀疏矩阵的(row ,col)位置写一个矩阵元素值x。
如果位置非法,你需要打印"SM_SetAt(): location error when writing elements of the matrix!",并退出整个程序执行(exit(0))。
如果位置合法,需要写入矩阵元素。

测试说明
平台会建立一个10×10的稀疏矩阵,对你编写的代码进行测试:

测试输入:1  2  0.1
预期输出:"correct!\n"

测试输入:11 12 0.2
预期输出:"SM_SetAt(): location error when writing elements of the matrix!"

开始你的任务吧,祝你成功!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "SparseMatrix.h"

SparseMatrix* SM_Create(int rows, int cols, int maxnodes)
// 创建一个稀疏矩阵。
{
	SparseMatrix* A=(SparseMatrix*)malloc(sizeof(SparseMatrix));
	A->nodes=SL_Create(maxnodes); //给三元组表分配内存
	A->Rows=rows;
	A->Cols=cols;	
	A->maxnodes=maxnodes;
	return A;
}

void SM_Free(SparseMatrix* A)
// 释放/删除 稀疏矩阵。
{
	SL_Free(A->nodes);
	free(A);
}

int SM_Length(SparseMatrix* A)
// 获取长度。
{
	return SL_Length(A->nodes);
}

//设计这个小函数很好用,给读和写矩阵元素带来方便
int SM_Loc(SparseMatrix* A, int row, int col ){
	if(row<0||row>=A->Rows||col<0||col>=A->Cols) {
		return -2;  // -2表示坐标非法 
	}
	else {
		for (int k=0;k<SL_Length(A->nodes);k++){
            T x=SL_GetAt(A->nodes, k); //在nodes表中取元素
            if(x.row ==row && x.col==col)
                   return k ; //查到了
        }   
        return -1;  //  没查到三元组元素 
	}
}

TV SM_GetAt(SparseMatrix* A, int row, int col)
// 获取稀疏矩阵的第row,col位置的数据。
{
	int loc= SM_Loc(A,row,col);
	if (loc==-2) {
		printf("SM_GetAt(): location error when reading elements of the matrix!\n");		
		SM_Free(A);
		exit(0);
	}
	else if (loc==-1)
	    return 0;
	else {
	    return SL_GetAt(A->nodes, loc).value;	
	}
	    
		
}

void SM_SetAt(SparseMatrix* A, int row, int col, TV x)
// 设置稀疏矩阵的第row,col位置的数据。
{
   //begin
 int loc= SM_Loc(A,row,col);
  if(loc==-2) //坐标不合法
  {
      printf("SM_SetAt(): location error when writing elements of the matrix!");
      exit(0);
  }
  else if(loc==-1)//nodes没有,稀疏矩阵里面的元素为0
  {
    A->nodes->len++;
    T y;
    y.row=row;
    y.col=col;
    y.value=x;
    A->nodes->data[0]=y;  
  }
  else {
     T y=SL_GetAt(A->nodes, loc);
     A->nodes->data[0]=y;
     

  }

   //end
}

void SM_Print(SparseMatrix* A)
// 打印整个顺序表。
{
	if (SL_Length(A->nodes)==0) {
		printf("The slist is empty.\n");		
		return;
	}

	for (int i=0; i<SL_Length(A->nodes); i++) {
		T x=SL_GetAt(A->nodes, i);
		printf("%d  %d  %lf\n", x.row, x.col, x.value);
	}
	
}

bool SM_Equal(SparseMatrix* A, SparseMatrix* B){
	if (A->Rows!=B->Rows || A->Cols != B->Cols) return false;
	if (SL_Length(A->nodes) != SL_Length(B->nodes)) return false;
	for (int i=0;i<SL_Length(A->nodes);i++){		
		T a=SL_GetAt(A->nodes,i);
		TV b=SM_GetAt(B,a.row,a.col);
		//printf("%f %f",a.value,b); 
		if (fabs(b-a.value)>SMALL) return false;		    
	}
	return true;
		
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值