最近做了一个老师布置的计算方法题目,是让读取文件后解方程的,用python读取后是乱码的,不太好搞,想到这是用C语言编的,不如就用C/C ++ 来解码(其实特别简单)。
数据文件:
链接:https://pan.baidu.com/s/1TzusBPi9FPDYTNCQil-P9w
提取码:1234
题目如下:
给定数据读取后求解线性方程组;
序号 | 数据文件 | 规模 | 类型 | 解 | 说明 |
1 | FuncData20211.dat | 16阶 | 非压缩格式 | 1.414 | 用于测试程序 |
2 | FuncData20212.dat | 16阶 | 压缩格式 | 1.732 | 用于测试程序 |
3 | FuncData20213.dat | 2000阶左右 | 非压缩格式 | 待解 | 用于程序求解 |
4 | FuncData20214.dat | 50000阶左右 | 压缩格式 | 待解 | 用于程序求解 |
5 | FuncData20215.dat | 13w阶左右 | 压缩格式 | 待解 | 测试软件功能 |
附3:线性方程组数据文件格式说明
线性方程组的系数矩阵和右端常量将全部以二进制格式存贮在一个数据文件中, 在使用时必须按指定结构使用二进制格式进行读取。
1.数据文件的文件名后缀为.dat,形式为:文件名.dat;
2.数据文件的结构,分为以下四个部分:
(1)文件类型标志部分:该部分存放本数据文件的描述信息,结构如下:
数据项 | 数据类型 | 说明 | |
1 | id | long int | 该数据文件的标识,值为0x 0C0A8708, |
2 | ver | long int | 数据文件的版本号,值为16进制数据,值的含义如下: (1)0x102: 系数矩阵为非压缩格式带状矩阵 (2)0x202: 系数矩阵为压缩格式带状矩阵 |
3 | id1 | long int | 备用标志字段,暂时未用 |
该部分的C语言格式描述为:
typedef struct FileInfo {
long int id; // 数据文件标示
long int ver; // 数据文件版本号
long int id1; // 备用标志
} FILEINFO;
(2)系数矩阵结构描述部分:该部分包括矩阵的阶数和上下带宽,如果是稀疏矩阵,则上下带宽值为0,结构如下:
数据项 | 数据类型 | 说明 | |
1 | n | long int | 方程组的阶数 |
2 | q | long int | 带状矩阵的上带宽, 如果是稀疏矩阵,则值为0 |
3 | p | long int | 带状矩阵下带宽, 如果是稀疏矩阵,则值为0 |
该部分的C语言格式描述为:
typedef struct HeadInfo {
long int n; // 方程组的阶数
long int q; // 上带宽
long int p; // 下带宽
} HEADINFO;
(3) 系数矩阵数据部分:该部分存放方程组系数矩阵中的所有元素
①若存贮格式为非压缩格式,则按行方式顺序存贮系数矩阵中的每一个元素,元素总个数为 ,每个元素的类型为float型;
②若存贮格式是压缩方式,则同样是按行方式进行存贮,但每行中只存放上下带宽内的非零元素,即每行中存贮的元素都为 个,不足个数者以0填充;
(4)右端系数部分:该部分按顺序存放方程组中的右端的每个系数,个数为n个,每个系数的类型均为float型。
C语言文件那一章当时没咋学,这次特地又回去学了一下:
回顾一下主要内容:
1,文本文件操作中,getc / putc 函数 , fscanf / fprintf 函数 , fgets / fgets 函数 , 但只能用于操作 文本文件 ; fread / fwrite 函数(读和写) 既可以操作 二进制文件 , 又可以操作 文本文件 ;
2.FILE *fp为文件指针,随着对文件的读写,文件的位置指针(指向当前读写字节)向后移动 ;fopen(),fclose( ),文件的打开和关闭功能
3,fseek()移动文件指针的位置;SEEK_END文件尾部,SEEK_SET文件头部 ,rewind() 将指针回到文件流的开头, ftell( ),输出文件的字节大小
可编写代码如下:(部分代码)
// 首先将数据文件放在C++ 项目文件下
char tempstr[5][20] = {"FuncData20211.dat", "FuncData20212.dat", \
"FuncData20213.dat", "FuncData20214.dat", "FuncData20215.dat"};
float A[3000][3000], b[3000], temp[3000];
int n, len; // 全局变量
void read(int i)
{
FILEINFO f;
HEADINFO h;
FILE *fp = fopen(tempstr[i], "rb");
if (!fp)
{
cout << "文件读入错误!" << endl;
return ;
}
//计算文件的大小
// fseek(fp, 0, SEEK_END);
// int size = ftell(fp);
// cout << size << endl;
// rewind(fp);
// 读入两个结构体头部的信息
fread(&f, sizeof (FILEINFO), 1, fp); // &f 为读入数据放入的地址, sizeof (FILEINFO) 为单个数据元素的字节大小, 1 是指读入1个数据元素,fp 为文件指针
fread(&h, sizeof (HEADINFO), 1, fp);
printf("%08x %08x %08x\n", f.id, f.ver, f.id1); //输出头部信息, 8个位宽,不足以0填充
printf("%08x %08x %08x\n", h.n, h.q, h.p);
n = h.n;
len = h.q + h.p + 1;
// 非压缩矩阵
if (f.ver == 0x102) {
for (int i = 0; i < n; i ++ )
{
if (fread(&A[i], sizeof (float), n, fp) != n)
{
cout << "矩阵读取错误!" << endl;
return ;
}
}
} else {
// 压缩矩阵
for (int i = 0; i < n; i ++ )
{
if (fread(&temp, sizeof (float), len, fp) != len)
{
cout << "矩阵读入错误!" << endl;
return ;
}
for (int j = 0; j < len; j ++ )
{
int pos = h.p - i;
if (pos > 0) A[i][j] = temp[j + pos];
else A[i][j - pos] = temp[j];
}
}
}
fread(&b, sizeof (float), n, fp); // 读右端系数b
fclose(fp);
//输出调试
// for (int i = 0; i < n; i ++ )
// {
// for (int j = 0; j < n; j ++ ) printf("%6.2f ", A[i][j]);
// printf("%6.2f\n", b[i]);
// }
}
读取前两个数据如下: