C++第四次作业

文章目录:

一: C++从键盘输入10个整数,用整型一维数组存储。要求输入时无序,输入完成后数组元素已按递增排序。输出此数组元素。(使用插入排序方法)

代码实现

运行结果

二:C++编制程序实现M*K阶矩阵A与K*N阶矩阵B的乘积矩阵C(M*N阶)的求解和输出,要求分别使用两种存储矩阵的方法(分别编程)

扩展 

代码实现

运行结果

三:C++编制程序用高斯顺序消元法求解n阶线性方程组在增广矩阵中讨论

方法一: 误差较大

代码实现

运行结果

方法二:误差较小

代码实现 

运行结果

方法三:误差最小

四:C++编写程序用高斯消元法(例如第3题中的系数矩阵:经2步消元后系数矩阵变换为上三角形矩阵,可以再做2步消元,将矩阵变换成对角线矩阵,最后再变换为单位矩阵)求n阶方阵的逆矩阵并验证正确与否。

方法一 :原理法

 方法二:公式法 

代码实现

运行结果


一: C++从键盘输入10个整数,用整型一维数组存储。要求输入时无序,输入完成后数组元素已按递增排序。输出此数组元素。(使用插入排序方法)

代码实现

#include <iostream>
using namespace std;


int main()
{
	int a[10] ;		//定义数组长度
	int i,j;		//定义变量

	//键盘循环输入10个数
	for (i = 0; i < 10; i++)
	{
		cout<< "请输入10个整数存到数组,第"<<i+1<<"次输入为:"<<endl;
		cin >>a[i];
	}
	//输出键盘的10个数
	cout<<"你输入的数组为:";
	 for(int i=0;i<10;i++)
		{
			cout<<a[i]<<"  ";
		}	
		  cout<<endl;

cout << "-----------------------------------------------------"<<endl;

	//开始排序
	for(i=1;i<10;i++)
		 {
		  //从后面无序的往前面有序的插
			 int temp = a[i];
			  for(j=i-1;j>=0;--j)
			  {
				 if(temp<a[j]){
					a[j+1]=a[j];//在有序列表中比arr[j]大的元素后移
				 }else
				 {
					 break;				//arr[j]大于有序表中的最后一位则不需要移动
				 }	  
			  }
		   a[j+1]=temp;		//跳出内层循环插在合适的位置
		 }
 
		 cout<<"其插入排序后为:";
		 for(int i=0;i<10;i++)
				{
				 cout<<a[i]<<"  ";
				}	
		  cout<<endl;


	 system("pause");
	return 0;
}

运行结果

二:C++编制程序实现M*K阶矩阵A与K*N阶矩阵B的乘积矩阵C(M*N阶)的求解和输出,要求分别使用两种存储矩阵的方法(分别编程)

  1. 用静态二维数组存储矩阵;例如Aij=a[i][j]
  2. 用静态一维数组存储矩阵。例如Aij=a[i*K+j]

注:矩阵的乘积——设A为m*k阶,B为k*n阶,则C为m*n阶,Cij=Ai0*B0j+……+ Ai,k-1*Bk-1,j

扩展 

              行 列

A:         M*K

B:         K*N

C=A*B:M*N 

矩阵相乘:左行*右列

               只有当左边矩阵的列数等于右边矩阵的行数时才能相乘

乘积矩阵:行数等于左边矩阵的行数;列数等于右边矩阵的列数

代码实现

#include <iostream>
using namespace std;
const int maxlong = 100;

int main()
{
	int M,K,N;

	//定义三个矩阵大小;初始化矩阵C
	int A[maxlong][maxlong],B[maxlong][maxlong],C[maxlong][maxlong]={0};


	//A: M*K      B: K*N         C:M*N
	cout<<"请输入你要相乘的行列大小!!!"<<endl;
	cout <<"请输入第一个矩阵的行大小:" <<endl;
	cin>>M;
	cout <<"请输入第一个矩阵的列大小——第二个矩阵的行大小:" <<endl;
	cin>>K;
	cout <<"请输入第二个矩阵的列大小:" <<endl;
	cin>>N;

	//矩阵A
	cout<<"请输入矩阵A:"<<endl;
	for(int i=0;i<M;i++){
		for(int j=0;j<K;j++){
			cin>>A[i][j];
		}
	}
			//输出矩阵A
			cout << "矩阵A为:"<<endl;
			cout <<"----------------------"<<endl;
			for(int i=0;i<M;i++){
				for(int j=0;j<K;j++){
					cout <<A[i][j]<< "\t";
				/*		if(j!=K-1){
							cout <<"  ";
						}*/
				}
				cout <<endl;
			}
			cout <<"----------------------"<<endl;



	//矩阵B
	cout<<"请输入矩阵B:"<<endl;
	for(int i=0;i<K;i++){
		for(int j=0;j<N;j++){
			cin>>B[i][j];
		}
	}
			//输出矩阵B
			cout << "矩阵B为:"<<endl;
			cout <<"----------------------"<<endl;
			for(int i=0;i<K;i++){
				for(int j=0;j<N;j++){
					cout <<B[i][j];
						if(j!=N-1){
						cout << "\t";
						}
				}
				cout <<endl;
			}
			cout <<"----------------------"<<endl;

	//乘积矩阵矩阵C
	for(int i=0;i<M;i++){							//第一个矩阵的行大小
		for(int j=0;j<N;j++){						//第二个矩阵的列大小
			for(int y=0;y<K;y++){					//第一个矩阵的列大小——第二个矩阵的行大小
				C[i][j] += A[i][y]*B[y][j];			//A数组中第i行第j列的值*B数组第y行第j列的值=C数组第i行第j列的值
			}
		}
	}

			//输出乘积矩阵矩阵C
			cout << "乘积矩阵矩阵C为:"<<endl;
			cout <<"----------------------"<<endl;
			for(int i=0;i<M;i++){
				for(int j=0;j<N;j++){
					cout <<C[i][j];
						if(j!=N-1){
							cout << "\t";
						}
				}
				cout <<endl;
			}
			cout <<"----------------------"<<endl;

	 system("pause");
	return 0;
}

运行结果

三:C++编制程序用高斯顺序消元法求解n阶线性方程组在增广矩阵中讨论

1.存取在二维数组中

2.首先要确定是几阶,n-1步消元

                 3阶 需要3-1=2步消元

3.如果为几阶:行为n;列为n+1

                 如果为3阶:行为3,列为4

                 如果为4阶:行为4,列为5

4.消元:消元到底n阶为止

                 3阶:第0行,第1行,第2行

                 第1步消元:

                          倍数1:m1=a[1][0]/a[0][0]                    第1行-第0行*m1=第1行

                          倍数2:m2=a[1][0]/a[0][0]                    第2行-第0行*m2=第2行

                 第2步消元:

                          倍数3:m3=a[2][0]/a[1][0]                    第2行-第行*m3=第2行

5.等式:几阶就是x几

                 倒着来:n行~1行

                               求得结果依次往上带入

                                6*x3=6                                         x3=1

                                3*x2+1*x3=-5                              x2=-2

                               2*x1+2*x2+3*x3=3                       x1=2

方法一: 误差较大

前面后面分开来,处理方法一样

代码实现

参考:https://blog.csdn.net/qq_26025363/article/details/53027926

#include<iostream>
#include <cmath>
using namespace std;

//定义是几个阶层
const int n = 3;

//定义实现n阶线性方程组的求解
//方程组前面部分		方程组后面部分		
void liu(double a[n][n], double b[n])
{
    //判断能否用高斯消元法,如果矩阵主对角线上有0元素存在是不能用的
    for (int i = 0; i < n; i++)
        if (a[i][i] == 0)
        {
            cout << "抱歉对角线有0元素,不能用高斯消元法!" << endl;
            return;
        }

    int i, j, k;
	//存储初等行变换的系数,用于行的相减
    double c[n];   


	//开始消元
    for (k = 0; k < n - 1; k++)							//总共n-1次
    {
        for (i = k + 1; i < n; i++)						//依次,求出第K次初等行变换的系数
            c[i] = a[i][k] / a[k][k];

        //依次,第K次的消元计算
        for (i = k + 1; i < n; i++)						//与上面相互对应
        {
            for (j = 0; j < n; j++)
            {
                a[i][j] = a[i][j] - c[i] * a[k][j];		//变换后的这一行更新
            }
            b[i] = b[i] - c[i] * b[k];					//后面部分也一样
        }
    }

//存储解
    double x[n];

    //先计算出最后一个未知数;
    x[n - 1] = b[n - 1] / a[n - 1][n - 1];				//积/因子=未知数

    //求出每个未知数的值,倒着来,从倒数第2个开始
		//几个未知量
		//当n=3时:1;0两种
    for (i = n - 2; i >= 0; i--)						//从第0个未知数~倒数第2个未知数
    {
        double sum = 0;	
		//层数
		//当n等于3时:i=1     i=0
		//            循环1次-循环2次;
        for (j = i + 1; j < n; j++)						//每一个方程   1,2
        {	
			//除开未知量的项
				//每一次,每组除开未知量的项的,及其和都不一样
            sum += a[i][j] * x[j];						//3*1;2*(-2)——累加
        }
		//(结果-除开未知量的项)/未知量项系数=结果
        x[i] = (b[i] - sum) / a[i][i];					//存储解的结果   [(-5)-1]/3=-2    {3-[3*1+2*(-2)]}/2=2
    }


//遍历输出解
    cout << " 这个n阶线性方程的各个解为:" << endl;
    cout << endl;
    for (i = 0; i < n; i++)     
        cout <<"x"<<i+1<<"="<< x[i] << endl;

}

int main (){
	//这里更具自己需要填写
	//输入n阶线性方程组的前面部分
	double a[3][3] = {2,2,3,4,7,7,-2,4,5};
	//输入n阶线性方程组的后面部分
	double b[3] = { 3,1,-7};

	//引用
	liu(a, b);

system("pause");
return 0;

}

运行结果

 

方法二:误差较小

分开来,但是这里是找出最大的主元来依次消元

 参考:https://blog.csdn.net/zzu_seu/article/details/84205089?utm_medium=distribute.wap_relevant.none-task-blog-title-9

代码实现 

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int m, n,i,j,k;			// 行:m   列:n
double a[100][100],temp[100],d;	//定义矩阵大小 ;和值存取数组;每行的倍数变量;
void main()
{
	cout << "温馨提示:请输入标准的数值,不然会出现无穷、分母为0、越界等情况!"<<endl;
	cout << "请输入系数矩阵的行数:";
	cin >> m;
	cout << "请输入系数矩阵的列数:";
	cin >> n;

	if (m <= 0 || n <= 0)
	{
		cout << "输入的格式有误!\n";
	}
	
			for (i = 0; i < m; i++)
			{
				cout << "请输入第" << i + 1 << "行"<<"的"<<n<<"个系数:"<<endl;;
				for (j = 0; j < n; j++)
				{
					cin >> a[i][j];
				}
			}

			cout << "请输入"<<m <<"个每行等式后面的值:"<<endl;;
			for (i = 0; i < m; i++)
			{
				cin >> a[i][n];
			}
		

		cout << "该方程组的增广矩阵为:\n";
		cout <<"---------------------------------------------"<<endl;
		for (i = 0; i < m; i++)
		{
			for (j = 0; j < n+1; j++)
			{
				cout << a[i][j]<<"\t ";
			}
			cout << "\n";
		}
		cout <<"---------------------------------------------"<<endl;



		//找列主元最大值
		for (k = 0; k < n - 1; k++) 
		{
			double max = 0;
			int hang=0,num=0;
			for (i = k; i < n; i++)
			{
				if (fabs(a[i][k]) > max)
				{
					max = fabs(a[i][k]);
					hang = i;
				}
			 }
			//对角线
			if (a[hang][k] == 0)
			{
				cout << "无法计算" << endl;
				return;
			}
			//换行
			if (k != hang) 
			{
				for (i = 0; i < m+1; i++)
				{
					temp[i] = a[k][i];
					a[k][i] = a[hang][i];
					a[hang][i] = temp[i];
				}
			}
			cout << "选取列主元之后的增广矩阵为:\n";
		cout <<"---------------------------------------------"<<endl;
			for (i = 0; i < m; i++)
			{
				for (j = 0; j < n + 1; j++)
				{
					cout << a[i][j] << "\t ";
				}
				cout << "\n";
			}
		cout <<"---------------------------------------------"<<endl;


			//开始消元
			for (i = k + 1; i < m; i++) 
			{
				d = a[i][k] / a[k][k];
				for (j = 0; j < n + 1; j++)
				{
					a[i][j] = a[i][j] - d * a[k][j];
				}
			}
		cout <<"---------------------------------------------"<<endl;
				cout << "消元后的增广矩阵为:\n";
				for (i = 0; i < m; i++)
				{
					for (j = 0; j < n + 1; j++)
					{
						cout << a[i][j] << " \t";
					}
					cout << "\n";
				}
		cout <<"---------------------------------------------"<<endl;
		}

		//存取解
		//将temp内存做初始化,内容全部设置为0,准备存放解向量
		memset(temp, 0, 2* sizeof(double)); 

		for (i = m-1; i >= 0; i--) 
		{		  
			d = 0;
			for (k = 0; k < n; k++)
			{
				d += temp[k] * a[i][k];	
			}
			temp[i] = (a[i][n] - d) / a[i][i];
		}


		//输出解
		cout << "此方程组的解为:"<<endl; 
		for (i = 0; i < m; i++) 
		{
			cout << " "<< fixed << setprecision(2)<<"x"<<i+1 <<"=" << temp[i]<<endl;//小数位数取舍
		}

		system("pause");
}

运行结果

 

方法三:误差最小

前面两种方法都有一个共同特点就是, 线性方程组 前面和后面分开输入,要么自己输入代码,要么自定输入

 

可以尝试按照每一行包括【前面未知量+等式后半部分】,然后打印出来,进行初等变换,最后求解,可能有一丢丢麻烦

四:C++编写程序用高斯消元法(例如第3题中的系数矩阵:经2步消元后系数矩阵变换为上三角形矩阵,可以再做2步消元,将矩阵变换成对角线矩阵,最后再变换为单位矩阵)求n阶方阵的逆矩阵并验证正确与否。

求逆矩阵的基本操作方法是取一个与A同阶的单位矩阵A_1

用高斯-约当消元法(矩阵的初等行变换)将A消元成为单位矩阵,消元操作同时作用于A_1

最终A_1即为A的逆阵,以4阶为例

方法一 :原理法

3阶以内的矩阵求逆矩阵的3种手算方法

1.原矩阵A   n*n

2.取一个与A同阶的单位矩阵E

3.一左一右,组成一个新的矩阵B  n*2n

4.开始消元

5.变成一右一左,构成一个新的矩阵B1   n*2n

6.右边矩阵A1,即为逆矩阵

 方法二:公式法 

参考:https://recomm.cnblogs.com/blogpost/5292287

代码实现

#include <cmath>
#include <malloc.h>
#include <iostream> 
#include <iomanip>
using namespace std; 
#define  N  10                //定义方阵的最大阶数为10


//函数的声明部分
float MatDet(float *p, int n);                    //求矩阵的行列式
float Creat_M(float *p, int m, int n, int k);    //求矩阵元素A(m, n)的代数余之式
void print(float *p, int n);                    //输出矩阵n*n
bool Gauss(float A[][N], float B[][N], int n);    //采用部分主元的高斯消去法求方阵A的逆矩阵B



int main()
{
    float *buffer, *p;            //定义数组首地址指针变量
    int row, num;                //定义矩阵的行数和矩阵元素个数
    int i, j;
    float determ;                //定义矩阵的行列式
    float a[N][N], b[N][N];
    int n;
    cout << "采用逆矩阵的定义法求矩阵的逆矩阵!\n";
    cout << "请输入矩阵的行数: ";
    cin >> row;
    num = 2 * row * row;
    buffer = (float *)calloc(num, sizeof(float));        //分配内存单元
    p = buffer;
    if (NULL != p)
    {
        for (i = 0; i < row; i++)
        {
            cout << "请输入逆矩阵的第" << i+1 << " 行: "<<endl;
            for (j = 0; j < row; j++)
            {
                cin >> *p++;
            }
        }
    }
    else
    {
        cout << "无法分配内存!\n";
    }
    cout << "你输入的矩阵为 : \n";
	cout<<"----------------------------------"<<endl;
    print(buffer, row);                //打印该矩阵
	cout<<"----------------------------------"<<endl;
     
    determ = MatDet(buffer, row);    //求整个矩阵的行列式
    p = buffer + row * row;
    if (determ != 0)
    {
        cout << "这个矩阵的行列式为: " << determ << endl;
        for (i = 0; i < row; i++)    //求逆矩阵
        {
            for (j = 0; j < row; j++)
            {
                *(p+j*row+i) = Creat_M(buffer, i, j, row)/determ;
            }
        }
		cout<<"----------------------------------"<<endl;
        cout << "求出的逆矩阵为: " << endl;
        print(p, row);                //打印该矩阵
		cout<<"----------------------------------"<<endl;
    } 
    else
    {
        cout << "行列式为0,没有逆矩阵!\n";
    }
    free(buffer);        //释放内存空间

	cout <<"开始验证:"<<endl;
    cout << "采用部分主元的高斯消去法求方阵的逆矩阵!\n";
    cout << "请输入方阵的阶数: ";
    cin >> n;
    cout << "请输入" << n << "阶方阵: \n";
    //输入一个n阶方阵
    for (i = 0; i < n; i++)
    {
		cout << "请输入验证矩阵的第" << i+1 << " 行: "<<endl;
        for (j = 0; j < n; j++)
        {
            cin >> a[i][j];
        }
    }
	cout<<"----------------------------------"<<endl;
	cout << "你输入的验证矩阵为 : \n";
     for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            cout << a[i][j]<<"  ";
        }
		cout <<endl;
    }
	cout<<"----------------------------------"<<endl;
    //运用高斯消去法求该矩阵的逆矩阵并输出
    if (Gauss(a, b, n))
    {   

        cout << "验证后,该方阵的逆矩阵为: \n";
		cout<<"----------------------------------"<<endl;
        for (i = 0; i < n; i++)
        {
            cout << setw(4);
            for (j = 0; j < n; j++)
            {	
                cout << b[i][j] << setw(10);
            }
            cout << endl;
        }
		cout<<"----------------------------------"<<endl;
    }    
    getchar();


    return 0;
}


//-----------------------------------------------
//功能: 求矩阵(n*n)的行列式
//入口参数: 矩阵的首地址,矩阵的行数
//返回值: 矩阵的行列式值
//----------------------------------------------
float MatDet(float *p, int n)
{
	cout <<"方法一:通过公式来求逆矩阵=矩阵*伴随矩阵" <<endl;
    int r, c, m;
    int lop = 0;
    float result = 0;
    float mid = 1;
    if (n != 1)
    {
        lop = (n == 2) ? 1 : n;            //控制求和循环次数,若为2阶,则循环1次,否则为n次
        for (m = 0; m < lop; m++)
        {
            mid = 1;            //顺序求和, 主对角线元素相乘之和
            for (r = 0, c = m; r < n; r++, c++)
            {
                mid = mid * (*(p+r*n+c%n));
            }
            result += mid;
        }
        for (m = 0; m < lop; m++)
        {
            mid = 1;            //逆序相减, 减去次对角线元素乘积
            for (r = 0, c = n-1-m+n; r < n; r++, c--)
            {
                mid = mid * (*(p+r*n+c%n));
            }
            result -= mid;
        }
    }
    else
        result = *p;
    return result;
}
//----------------------------------------------------------------------------
//功能: 求k*k矩阵中元素A(m, n)的代数余之式
//入口参数: k*k矩阵的首地址,矩阵元素A的下标m,n,矩阵行数k
//返回值: k*k矩阵中元素A(m, n)的代数余之式
//----------------------------------------------------------------------------
float Creat_M(float *p, int m, int n, int k)
{
    int len;
    int i, j;
    float mid_result = 0;
    int sign = 1;
    float *p_creat, *p_mid;
    len = (k-1)*(k-1);            //k阶矩阵的代数余之式为k-1阶矩阵
    p_creat = (float*)calloc(len, sizeof(float)); //分配内存单元
    p_mid = p_creat;
    for (i = 0; i < k; i++)
    {
        for (j = 0; j < k; j++)
        {
            if (i != m && j != n) //将除第i行和第j列外的所有元素存储到以p_mid为首地址的内存单元
            {
                *p_mid++ = *(p+i*k+j);
            }
        }
    }
    sign = (m+n)%2 == 0 ? 1 : -1;    //代数余之式前面的正、负号
    mid_result = (float)sign*MatDet(p_creat, k-1);
    free(p_creat);
    return mid_result;
}
//-----------------------------------------------------
//功能: 打印n*n矩阵
//入口参数: n*n矩阵的首地址,矩阵的行数n
//返回值: 无返回值
//-----------------------------------------------------
void print(float *p, int n)
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        cout << setw(4);
        for (j = 0; j < n; j++)
        {
            cout << setiosflags(ios::right) << *p++ << setw(10);
        }
        cout << endl;
    }
}
//------------------------------------------------------------------
//功能: 采用部分主元的高斯消去法求方阵A的逆矩阵B
//入口参数: 输入方阵,输出方阵,方阵阶数
//返回值: true or false
//-------------------------------------------------------------------
bool Gauss(float A[][N], float B[][N], int n)
{
	cout <<"方法二:通过高斯消去法求逆矩阵" <<endl;
    int i, j, k;
    float max, temp;
    float t[N][N];                //临时矩阵
    //将A矩阵存放在临时矩阵t[n][n]中
    for (i = 0; i < n; i++)        
    {
        for (j = 0; j < n; j++)
        {
            t[i][j] = A[i][j];
        }
    }
    //初始化B矩阵为单位阵
    for (i = 0; i < n; i++)        
    {
        for (j = 0; j < n; j++)
        {
            B[i][j] = (i == j) ? (float)1 : 0;
        }
    }
    for (i = 0; i < n; i++)
    {
        //寻找主元
        max = t[i][i];
        k = i;
        for (j = i+1; j < n; j++)
        {
            if (fabs(t[j][i]) > fabs(max))
            {
                max = t[j][i];
                k = j;
            }
        }
        //如果主元所在行不是第i行,进行行交换
        if (k != i)
        {
            for (j = 0; j < n; j++)
            {
                temp = t[i][j];
                t[i][j] = t[k][j];
                t[k][j] = temp;
                //B伴随交换
                temp = B[i][j];
                B[i][j] = B[k][j];
                B[k][j] = temp; 
            }
        }
        //判断主元是否为0, 若是, 则矩阵A不是满秩矩阵,不存在逆矩阵
        if (t[i][i] == 0)
        {
            cout << "这里没有逆矩阵!";
            return false;
        }
        //消去A的第i列除去i行以外的各行元素
        temp = t[i][i];
        for (j = 0; j < n; j++)
        {
            t[i][j] = t[i][j] / temp;        //主对角线上的元素变为1
            B[i][j] = B[i][j] / temp;        //伴随计算
        }
        for (j = 0; j < n; j++)        //第0行->第n行
        {
            if (j != i)                //不是第i行
            {
                temp = t[j][i];
                for (k = 0; k < n; k++)        //第j行元素 - i行元素*j列i行元素
                {
                    t[j][k] = t[j][k] - t[i][k]*temp;
                    B[j][k] = B[j][k] - B[i][k]*temp;
                }
            }
        }
    }
    getchar();
    return true;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘鑫磊up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值