对于作业,我试图根据行和列的输入获取矩阵的子集。到目前为止,以下是我的代码,它打算从用户确定的nxm大小的文本文件中读取数字。
我不知道如何根据行和列从较大的矩阵中提取较小的2x2矩阵例如,如果大矩阵为:
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
而且我想从第2行和第3列开始提取
我想离开
7 8
2 3
它是代码的结尾(在矩阵行列式函数中),我希望将其提取并存储在我创建的结构矩阵中。提取的矩阵将从用户选择的起点行和列开始是连续的]
到目前为止的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//creating a variable type for the matrix created
struct matrix
{
char name;
float mValues[10][10];
int nrows;
int ncols;
};
//Function declarations
void matrixInput(struct matrix *mat, FILE *in);
void matrixDisplay(struct matrix mat);
float matrixDeterminant(struct matrix m1, struct matrix *m2, int *check);
int main()
{
FILE *fin; //fin = fopen("matrix.txt","r")
struct matrix matA;
struct matrix matB;
float determinant;
int i,j,flag;
fin=fopen("matrix.txt","r");
if (fin!=NULL)
{
printf("File was found!\n");
matrixInput(&matA,fin); //Function call to create matrix
matrixDisplay(matA); //Function call to display the created matrix
determinant=matrixDeterminant(matA,&matB,&flag);
matrixDisplay(matB);
}
else printf("File not found\n");
}
void matrixInput(struct matrix *mat, FILE *in)
{
int i;
int j;
struct matrix matA;
in=fopen("matrix.txt","r");
/*Asks for a single character input to name the matrix the user is creating*/
printf("Enter a single character name for your matrix e.g A,B...\n");
scanf("%c",&(*mat).name);
/*Asks for a number of rows of the matrix, valid answers are between and equal to 1 and 10. If these conditions aren't met the program will keep
prompting for a input that is valid*/
printf("Enter number of rows in the matrix less than or equal to 10\n");
scanf("%d",&(*mat).nrows);
while ((*mat).nrows > 10 || ((*mat).nrows < 1))
{
printf("Input is not valid, please enter another number\n");
scanf("%d",&(*mat).nrows);
}
/*Asks for a number of columns of the matrix, valid answers are between and equal to 1 and 10. If these conditions aren't met the program will
keep prompting for a input that is valid*/
printf("Enter number of columns in the matrix less than or equal to 10\n");
scanf("%d",&(*mat).ncols);
while ((*mat).ncols > 10 || (*mat).ncols < 1)
{
printf("Input is not valid, please enter another number\n");
scanf("%d",&(*mat).ncols);
}
for(i=0; i<(*mat).nrows; i++) //looping for number of rows user has entered
{
for(j=0; j<(*mat).ncols;j++) //looping for number of columns user has entered
{
fscanf(in,"%f",&(*mat).mValues[i][j]); //reading numbers from file and storing them into a 2D array
}
}
}
void matrixDisplay(struct matrix mat)
{
int i,j;
printf("\nMatrix name: %c Number of rows are: %d Number of columns are: %d\n\n",mat.name,mat.nrows,mat.ncols); //Prints the name of the matrix to screen
for(i=0; i<mat.nrows;i++)
{
printf("Row: %d",(i));
for(j=0; j<mat.ncols;j++)
{
printf("%8.2f",mat.mValues[i][j]);
}
printf("\n");
}
}
float matrixDeterminant(struct matrix m1, struct matrix *m2, int *check)
{
FILE *fin;
int Rowslim,Colslim,choicecol,choicerow,i,j;
struct matrix matA;
struct matrix matB;
Rowslim=m1.nrows-1;
Colslim=m1.ncols-1;
fflush(stdin);
printf("Please enter a single character name of the 2x2 matrix\n");
scanf("%c",&(*m2).name);
printf("Please enter a row number where 2x2 matrix should start, must be between 0 and %d\n",Rowslim);
scanf("%d",&choicerow);
printf("please enter a column number where 2x2 matrix should start, must be between 0 and %d\n",Colslim);
scanf("%d",&choicecol);
(*m2).nrows=2;
(*m2).ncols=2;
fin=fopen("matrix.txt","r");
{
for(i=0; i<(choicerow-1); i++) //looping for number of rows user has entered
{
for(j=0; j<(choicecol-1);j++) //looping for number of columns user has entered
{
fscanf(fin,"%f",&(*m2).mValues[i][j]);
}
fscanf(fin,"%f",&(*m2).mValues[i][j]);
}
}
}
这是我用来将正方形子矩阵从一个矩阵复制到单独矩阵中的代码:
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
enum { MAX_MATRIX_SIZE = 10 };
struct matrix
{
char name;
float mValues[MAX_MATRIX_SIZE][MAX_MATRIX_SIZE];
int nrows;
int ncols;
};
typedef struct matrix Matrix;
static void matrixDisplay(const Matrix *mat);
static int matrixExtractSubMatrix(Matrix *m2, const Matrix *m1, char name,
int r0, int c0, int size);
int main(void)
{
Matrix matA =
{
.name = 'A', .nrows = 4, .ncols = 4,
.mValues =
{
{ 1, 2, 3, 4, }, { 5, 6, 7, 8, },
{ 9, 1, 2, 3, }, { 4, 5, 6, 7, },
},
};
matrixDisplay(&matA);
Matrix matB;
for (int i = 0; i < matA.nrows - 2 + 1; i++)
{
for (int j = 0; j < matA.ncols - 2 + 1; j++)
{
if (matrixExtractSubMatrix(&matB, &matA, 'B', i, j, 2) != 0)
fprintf(stderr, "Failed to extract sub-matrix\n");
matrixDisplay(&matB);
}
}
return 0;
}
static void matrixDisplay(const Matrix *mat)
{
printf("\nMatrix %c (%dx%d):\n", mat->name, mat->nrows, mat->ncols);
for (int i = 0; i < mat->nrows; i++)
{
printf("Row: %d:", i);
for (int j = 0; j < mat->ncols; j++)
printf(" %8.2f", mat->mValues[i][j]);
printf("\n");
}
}
static int matrixExtractSubMatrix(Matrix *m2, const Matrix *m1, char name,
int r0, int c0, int size)
{
assert(m2 != NULL && m1 != NULL);
assert(r0 >= 0 && r0 + size <= m1->nrows);
assert(c0 >= 0 && c0 + size <= m1->ncols);
if ((r0 < 0 || r0 + size > m1->nrows) ||
(c0 < 0 || c0 + size > m1->ncols))
return -1;
m2->name = name;
m2->nrows = size;
m2->ncols = size;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
m2->mValues[i][j] = m1->mValues[r0 + i][c0 + j];
}
return 0;
}
没有什么特别的。通过将矩阵结构作为指针传递,而不是复制整个结构,可以避免将412个字节复制到堆栈中。除static
外,所有功能均为main()
。如果功能需要在此文件之外可见,则应在标头中声明它们。没有标头,因此在该文件外部不需要可见的功能(main()
除外)。现在,数组在Matrix
结构中的尺寸(最初是struct matrix
,但为方便起见将类型定义为Matrix
)是一个枚举常量,因此可以在代码中使用它来指定数组中的最大尺寸。结构。
我消除了文件输入和行列式功能;矩阵是硬编码的。
测试代码将打印所有非包装的2x2子矩阵:
Matrix A (4x4):
Row: 0: 1.00 2.00 3.00 4.00
Row: 1: 5.00 6.00 7.00 8.00
Row: 2: 9.00 1.00 2.00 3.00
Row: 3: 4.00 5.00 6.00 7.00
Matrix B (2x2):
Row: 0: 1.00 2.00
Row: 1: 5.00 6.00
Matrix B (2x2):
Row: 0: 2.00 3.00
Row: 1: 6.00 7.00
Matrix B (2x2):
Row: 0: 3.00 4.00
Row: 1: 7.00 8.00
Matrix B (2x2):
Row: 0: 5.00 6.00
Row: 1: 9.00 1.00
Matrix B (2x2):
Row: 0: 6.00 7.00
Row: 1: 1.00 2.00
Matrix B (2x2):
Row: 0: 7.00 8.00
Row: 1: 2.00 3.00
Matrix B (2x2):
Row: 0: 9.00 1.00
Row: 1: 4.00 5.00
Matrix B (2x2):
Row: 0: 1.00 2.00
Row: 1: 5.00 6.00
Matrix B (2x2):
Row: 0: 2.00 3.00
Row: 1: 6.00 7.00
可以将其重命名为matrixExtractSquareSubMatrix()
并创建另一个函数matrixExtractSubMatrix()
,该函数将分别告诉您要复制多少行和几列:
int matrixExtractSubMatrix(Matrix *m2, const Matrix *m1, char name,
int r0, int c0, int ncols, int nrows);
然后您可以将matrixExtractSquareSubMatrix()
编写为内联函数,以调用matrixExtractSubMatrix()
两次传递size
参数。
我不相信创建这样的子矩阵会很有效,但是与'正确'相比,这是一个附属问题。