您的位置:首页 > 其它

逆序数&行列式&矩阵乘法&逆矩阵【线性代数】

2017-11-15 21:58 429 查看
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cmath>
#include<map>
#include<string>
#include<functional>
using namespace std;
const int maxn = 12;
string str;
map<string, int>mp;
map<int, string>rmp;
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a%b);
}
struct Dmt {//行列式
int x;
int y;
int a[maxn][maxn];
};
struct Mat {//矩阵
int x;
int y;
int a[maxn][maxn];
};
int determinant_1(Dmt tmp)
{
int a_1 = tmp.a[1][1];
return a_1;
}
int determinant_2(Dmt tmp)
{
int a_1 = tmp.a[1][1] * tmp.a[2][2];
int a_2 = tmp.a[1][2] * tmp.a[2][1];
return a_1 - a_2;
}
int determinant_3(Dmt tmp)
{
int a_1 = tmp.a[1][1] * tmp.a[2][2] * tmp.a[3][3];
int a_2 = tmp.a[1][2] * tmp.a[2][3] * tmp.a[3][1];
int a_3 = tmp.a[1][3] * tmp.a[2][1] * tmp.a[3][2];
int a_4 = tmp.a[1][3] * tmp.a[2][2] * tmp.a[3][1];
int a_5 = tmp.a[1][1] * tmp.a[2][3] * tmp.a[3][2];
int a_6 = tmp.a[1][2] * tmp.a[2][1] * tmp.a[3][3];
return a_1 + a_2 + a_3 - a_4 - a_5 - a_6;
}
int get_determinant(Dmt tmp, int ans)//ans——当前行列式的值
{
Dmt newtmp;
if (tmp.x == 1 && tmp.y == 1)
return determinant_1(tmp);
if (tmp.x == 2 && tmp.y == 2)
return determinant_2(tmp);
if (tmp.x == 3 && tmp.y == 3)
return determinant_3(tmp);
//按照最后一行的代数余子式展开~
newtmp.x = tmp.x - 1;
//cout << newtmp.x << endl;
newtmp.y = tmp.y - 1;
//cout << newtmp.y << endl;
int cnt = ans;
for (int i = 1; i <= tmp.x; i++)//按照最后一行展开成代数余子式!
{
for (int j = 1; j <= tmp.x - 1; j++)
{
int cs = 1;
for (int k = 1; k <= tmp.y; k++)
{
if (k == i)
continue;
newtmp.a[j][cs] = tmp.a[j][k];
cs++;
}
}
cnt += (int)pow(-1, tmp.y + i)*tmp.a[tmp.y][i] * get_determinant(newtmp, 0);
}
return cnt;
}
void solve_determinant()
{
printf("请输入行列式的行数、列数\n");
Dmt test;
//  int x; int y;
scanf("%d%d", &test.x, &test.y);
printf("读取成功,请输入行列式\n");
for (int i = 1; i <= test.x; i++)
{
for (int j = 1; j <= test.y; j++)
{
scanf("%d", &test.a[i][j]);
}
}
printf("%d\n", get_determinant(test, 0));
}
int get_inversion_pair(int cnt, int b[])
{
int ans = 0;
for (int i = 1; i <= cnt; i++)
{
for (int j = i + 1; j <= cnt; j++)
{
if (b[j] < b[i])
ans++;
}
}
return ans;
}
void solve_inversion_num()
{
printf("请输入序列的长度\n");
int n; int a[12];
scanf("%d", &n);
printf("请输入序列元素(请用空格分隔)\n");
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
printf("%d\n", get_inversion_pair(n, a));
}
Mat get_matrix_multiplication(Mat A, Mat B)//预处理判断矩阵是否可以相乘
{
Mat newtmp;
int m = A.x, s = A.y, n = B.y;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
newtmp.a[i][j] = 0;//矩阵初始化
}
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
for (int k = 1; k <= s; k++)
{
newtmp.a[i][j] += A.a[i][k] * B.a[k][j];
}
}
}
return newtmp;
}
void solve_matrix_multiplication()
{
Mat A, B, ans;
printf("请输入矩阵A的长和宽\n");
scanf("%d %d", &A.x, &A.y);
printf("请输入矩阵B的长和宽\n");
scanf("%d %d", &B.x, &B.y);
if (A.y != B.x)
{
printf("输入非法 无法相乘\n");
return;
}
printf("请输入矩阵A\n");
for (int i = 1; i <= A.x; i++)
{
for (int j = 1; j <=A.y; j++)
{
scanf("%d", &A.a[i][j]);
}
}
printf("读取成功,请输入矩阵B\n");
for (int i = 1; i <= B.x; i++)
{
for (int j = 1; j <= B.y; j++)
{
scanf("%d", &B.a[i][j]);
}
}
int m = A.x, s = A.y, n = B.y;
ans = get_matrix_multiplication(A, B);//完成计算 得到新矩阵ans
printf("%d %d\n", m, n);
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (j!=1)
printf(" ");
printf("%d", ans.a[i][j]);
}
printf("\n");
}
}
void get_inverse_matrix(Mat A)//根据公式A^-1=1/|A|*伴随A
{
Dmt tmp;//行列式
Mat ans;//矩阵
Dmt cnt;//行列式
cnt.x = A.x;
cnt.y = A.y;
ans.x = A.x;
ans.y = A.y;
tmp.x = A.x - 1;
tmp.y = A.y - 1;
for (int i = 1; i <= cnt.x; i++)
{
for (int j = 1; j <= cnt.y; j++)
{
cnt.a[i][j] = A.a[i][j];
}
}
for (int i = 1; i <= A.x; i++)
{
for (int j = 1; j <= A.y; j++)
{
int cs = 1; int ct = 1;
for (int k = 1; k <= A.x; k++)
{
ct = 1;
if (k == i)
continue;
for (int p = 1; p <= A.y; p++)
{
if (p == j)
continue;
tmp.a[cs][ct] = A.a[k][p];
ct++;
}
cs++;
}
//cout << cs << " " << ct << endl;
ans.a[i][j] = (int)pow(-1, i + j)*get_determinant(tmp, 0);
//cout << ans.a[i][j] << endl;
}
}
int hlsA = get_determinant(cnt, 0);
printf("%d\n", hlsA);
for (int i = 1;i<=ans.x;i++)
{
for (int j=1;j<=ans.y;j++)
{
if (j != 1)
printf(" ");
int temp = gcd(hlsA, ans.a[j][i]);
if (ans.a[j][i] % hlsA == 0)
{
printf("%d  ", ans.a[j][i] / hlsA);
}
else
{
printf("%d/%d", ans.a[j][i] / temp, hlsA / temp);
}
}
printf("\n");
}
}
void solve_inverse_matrix()
{
Mat A, B;
printf("请输入矩阵的长和宽\n");
scanf("%d%d", &A.x, &A.y);
printf("读取成功,请输入矩阵的元素\n");
for (int i = 1; i <= A.x; i++)
{
for (int j = 1; j <= A.y; j++)
{
scanf("%d", &A.a[i][j]);
}
}
get_inverse_matrix(A);
/*for (int i = 1; i <= B.x; i++)
{
for (int j = 1; j <= B.y; j++)
{
if (j != 1)
printf(" ");
printf("%d", B.a[i][j]);
}
printf("\n");
}*/
}
int main()
{
printf("祝您考试取得佳绩!\n");
mp.clear();
mp["hls"] = 1;//行列式
mp["nxs"] = 2;//逆序数
mp["jzcf"] = 3;//矩阵乘法
mp["njz"] = 4;//逆矩阵
//cin.ignore();
while (cin>>str)
{
//printf("%d\n", mp.count(str));
if (mp.count(str))
{
printf("读取成功\n");
if (str == "hls")
solve_determinant();
else if (str == "nxs")
solve_inversion_num();
else if (str == "jzcf")
solve_matrix_multiplication();
else if (str == "njz")
solve_inverse_matrix();
}
else
{
printf("读取失败,请重新输入\n");
}
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: