C + + implementation of row minimalist matrix

Yesterday, I learned the calculation method of the line simplest matrix of linear algebra. The idea is relatively simple, but it is troublesome to do so. Therefore, I consulted some materials and wrote a code implemented in C + +. I have written detailed comments on the code and it has been successfully compiled and run in VS2015. You can read it at ease;

// ConsoleApplication1.cpp: defines the entry point for the console application.

#include "stdafx.h"
#include<math.h>
#include<stdlib.h>
//Define two macros, M represents the number of rows of the matrix, N represents the number of columns of the matrix
#define M 4
#define N 4   
using namespace std;
//The flag array is used to identify whether the data of a column is 0. If flag[n]=0, the column is not 0
int flag[M];
int count1[M];//The number of elements used to store 3 rows with data of 0 from the beginning
//Function of output matrix
void print(float(*a)[N])//The following parameters are of float type, which can be used in a wider range
{
	int i, j;
	for (i = 0; i < M; i++) //Two layer circular printing
	{
		for (j = 0; j < N; j++)
		{
			if (fabs(a[i][j]) < 0.000001) //Judge whether it is zero first
				a[i][j] = 0;
			cout << a[i][j] << "   ";
		}
		cout << endl;  //Print one whole line, enter, print next line
	}
}
//Count the number of elements with 0 from the beginning of each row of the matrix and assign it to the array count1. For example, if 0.12.04 is used, it will be counted as 1;
 void statistics(float(*a)[N])
{
	int i = 0, j = 0;
	for (i = 0; i<M; i++) //Row loop on the first level
	{
		int n = 0;
		for (j = 0; j<M; j++)  //Bilevel cycle
			if (fabs(a[i][j])<0.000001)
			{
				n++;
				count1[i] = n;  //If it is zero, the counter is added and assigned to the corresponding element of array count1
			}
			else
			{
				count1[i] = n;
				break;
			}
	}
}
 //Function to exchange two rows of data
void exchange(float a[], float b[]) 
{
	float t;//Define temporary variable exchange data
	for (int i = 0; i<N; i++)
	{
		t = a[i];
		a[i] = b[i];
		b[i] = t;
	}
}
//Make a data 1
void change1(float a[], float b)
{
	for (int i = 0; i<N; i++)
		a[i] /= b;
}
//Determine whether the data of a column is 0, and assign 1 or 0 to the array flag [];
void judgement(float *p)
{
	for (int i = 0; i<M; i++)
		if (fabs(p[N*i])<0.000001)
			flag[i] = 0;
		else
			flag[i] = 1;
}
//Subtract the product of the data in row a and the data in row b from the data in row b, and assign the difference to the data in row b in turn
void subtraction(float a[], float b[], float rb)
{
	for (int i = 0; i<N; i++)
		b[i] = b[i] - a[i] * rb;
}
int main()
{
	cout <<"Please enter a" << M << "That's ok" << N << "Matrix of columns:" << endl;
	float Matrix[M][N];
	int i = 0, j = 0;
	//Initialize assignment
	for (i = 0; i<M; i++)
		for (j = 0; j<N; j++)
			cin >> Matrix[i][j];

	cout << "The original matrix:" << endl;
	print(Matrix);
	cout << endl;
	//Core code
		for (j = 0; j<N; j++)
	{
		//Count the number of elements with data of 0 from the beginning of each row and assign them to the array count1
		statistics(Matrix);

		/*Put the row with more elements of 0 from the beginning of the row to the bottom of the matrix, and use the idea of selective sorting,
		The minimum value is found first, and then exchanged with the first element. This method reduces the exchange times to a certain extent, and improves the running efficiency of the program;*/
		for (int h = 0; h<M - 1; h++)
		{
			int min = count1[h], tag = h;
			for (int k = h + 1; k <= M - 1; k++)
				if (min>count1[k])
				{
					min = count1[k];
					tag = k;
				}
			exchange(*(Matrix + h), *(Matrix + tag));
		}
		//After row exchange, count the number of elements whose data is 0 continuously from the beginning of each row and assign them to the array count1
		statistics(Matrix);
		cout << endl;
		//Determine whether the data in column j is 0, and assign 1 or 0 to the flag array
		judgement(*Matrix + j);

		//If the data in front of the line is 0, that is count [k] = = J (or the column is the first column) and the data in the column of the line is not 0, set the line to 1
		for (int k = 0; k<M; k++)
			if ((j == 0 || count1[k] == j) && (flag[k] == 1))
				change1(*(Matrix + k), Matrix[k][j]);//If the above conditions are met, divide row K by Matrix[k][j] and set 1;
		
		//The row number of the auxiliary basic row used to label other rows to 0. The element in front of the row is 0, and the element on the column is 1
		int label = -1;
		for (int k1 = 0; k1<M; k1++)
			//Judgment condition: if the data in front of this line is 0, then count [k] = = J (or this column is the first column) and the data in this column is not 0
			if ((j == 0 || count1[k1] == j) && (flag[k1] == 1))
			{
				label = k1;
				break;
			}
		if (label != -1)
		{
			for (int k2 = 0; k2<M; k2++)
				if ((k2 != label) && (flag[k2] == 1))
					subtraction(Matrix[label], Matrix[k2], Matrix[k2][j]);
		}
	}
	cout << "The row simplest matrix of the original matrix is:" << endl;
	print(Matrix);
	cout << endl;
	system("pause");
	return 0;
}

The running example of the program is as follows:

Note: the program has some limitations. It can't input program parameters dynamically. It can only modify the macro defined in the program source code to achieve the purpose;

Syntax level: This is because the C/C + + array is a static array, that is, when compiling, memory will be allocated to the array. At this time, even if the array length is a variable that has been assigned, the compiler will proudly report an error;
In order to realize the dynamic array, we need to use pointer. The process is very complicated. There are many methods on the Internet, which can be used for reference.

For compiler level, all kinds of compilers can support C89 standard very well, but the support for C99 is different: GCC of open source organization and LLVM/Clang used by Xcode have supported most (almost all) C99 standards, while VC and VS of Microsoft are not interested in C99, and they were not slowly supported until later VS2013, VS2015 and VS2017, and the support is not good.

  1. In C89, a constant expression must be used to indicate the array length; that is, the array length cannot contain a variable, regardless of whether it is initialized or not.
  2. In C99, you can use variables to indicate the array length. For example:
int m;
cin>>m;
int n[m];

The above code uses variables to indicate the array length, which can be compiled under GCC and Xcode, while errors will be reported under VC and vs (including VC 6.0, VS2010, VS2013, VS2015, VS2017, etc.).

Personal thoughts:
Program input is not very convenient, every time to manually input the matrix value;
Then the idea is: can I call the interface to recognize the matrix picture, and pass the recognized numbers into the parameters in the order of the matrix; can I call the voice recognition interface to recognize the matrix values of people in order, and pass them into the parameters; at present, my strength is limited, so I can't realize the above intelligent functions, but I have ideas and ideas to further improve the program. If you have any suggestions, please mention them and make progress together! Hope to encourage each other!

Reference blog: Sun Qun's blog

Published 14 original articles, won praise 28, visited 3274
Private letter follow

Tags: xcode

Posted on Fri, 21 Feb 2020 01:47:15 -0500 by BKPARTIES