作業要求:
使用一維指標來模擬二維陣列。
使用Command line argument list選擇尺寸、算法、輸入方式。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <string.h> | |
int IsMi0(float M[99][99], int x, int N) //指標判斷某列元素是否全為0 | |
{ | |
int y; | |
for (y = 0; y < N; y++) | |
if (M[x][y] == 0) | |
break; | |
if (y == N - 1) | |
return 1; | |
else | |
return 0; | |
} | |
int IsMi0_ptr(float *M, int x, int N) //指標判斷某列元素是否全為0 | |
{ | |
int y; | |
for (y = 0; y < N; y++) | |
if (*(M + x * 99 + y) == 0) | |
break; | |
if (y == N - 1) | |
return 1; | |
else | |
return 0; | |
} | |
void add(float R[99][99], float M1[99][99], float M2[99][99], int N) //宣告函數 | |
{ | |
int i, j; | |
FILE *out; | |
out = fopen("result", "w+"); | |
for (i = 0; i < N; i++) { //進行矩陣加法運算 | |
for (j = 0; j < N; j++) | |
R[i][j] = M1[i][j] + M2[i][j]; | |
} | |
for (i = 0; i < N; i++) { //印出結果矩陣 | |
for (j = 0; j < N; j++) | |
fprintf(out, "%.2f ", R[i][j]); | |
fprintf(out, "\n"); | |
} | |
fclose(out); | |
} | |
void multiplication(float R[99][99], float M1[99][99], float M2[99][99], int N) //宣告函數 | |
{ | |
int i, j, k; | |
FILE *out; | |
out = fopen("result", "w+"); | |
for (i = 0; i < N; i++) { //進行矩陣乘法運算 | |
for (k = 0; k < N; k++) { | |
for (j = 0; j < N; j++) | |
R[i][k] += M1[i][j] * M2[j][k]; | |
} | |
} | |
for (i = 0; i < N; i++) { //印出結果矩陣 | |
for (j = 0; j < N; j++) | |
fprintf(out, "%.2f ", R[i][j]); | |
fprintf(out, "\n"); | |
} | |
fclose(out); | |
} | |
void inverse(float R[99][99], float M[99][99], int N) //宣告函數 | |
{ | |
int x, y, k; | |
float temp; | |
FILE *out; | |
out = fopen("result", "w+"); | |
for (k = 0; k < N; k++) //設定單位矩陣 | |
R[k][k] = 1; | |
for (k = 0; k < N; k++) { | |
if ((IsMi0(M, k, N) == 1)) { //判斷某列是否全為0,若成立則反矩陣不存在。 | |
printf("This matrix has no inverse.\n"); | |
return; | |
} | |
if (M[k][k] == 0) { //若斜對角線之元素有0,則進行列交換。 | |
for (x = k + 1; x < N; x++) { | |
for (y = 0; y < N; y++) { | |
temp = M[k][y]; | |
M[k][y] = M[x][y]; | |
M[x][y] = temp; | |
temp = R[k][y]; | |
R[k][y] = R[x][y]; | |
R[x][y] = temp; | |
} | |
if (M[k][k] != 0) | |
break; | |
} | |
if (M[k][k] == 0) { //若無法交換至對角線無0,則反矩陣不存在。 | |
printf("This matrix has no inverse.\n"); | |
return; | |
} | |
} | |
temp = 1 / M[k][k]; //進行高斯喬登消去法解反矩陣。 | |
for (y = 0; y < N; y++) { | |
M[k][y] *= temp; | |
R[k][y] *= temp; | |
} | |
for (x = 0; x < N; x++) { | |
if (x == k) | |
continue; | |
temp = M[x][k] / M[k][k]; | |
for (y = 0; y < N; y++) { | |
M[x][y] -= temp * M[k][y]; | |
R[x][y] -= temp * R[k][y]; | |
} | |
} | |
temp = 1 / M[k][k]; | |
for (y = 0; y < N; y++) { | |
M[k][y] *= temp; | |
R[k][y] *= temp; | |
} | |
} | |
for (x = 0; x < N; x++) { | |
for (y = 0; y < N; y++) | |
fprintf(out, "%.3f ", R[x][y]); | |
fprintf(out, "\n"); | |
} | |
} | |
void add1(float *R, float *M1, float *M2, int N) //宣告函數 | |
{ | |
int i, j; | |
FILE *out; | |
out = fopen("result", "w+"); | |
for (i = 0; i < N; i++) { //進行矩陣加法運算 | |
for (j = 0; j < N; j++) | |
*(R + i * N + j) = *(M1 + i * 99 + j) + *(M2 + i * 99 + j); | |
} | |
for (i = 0; i < N; i++) { //印出結果矩陣 | |
for (j = 0; j < N; j++) | |
fprintf(out, "%.2f ", *(R + i * 99 + j)); | |
fprintf(out, "\n"); | |
} | |
fclose(out); | |
} | |
void multiplication1(float *R, float *M1, float *M2, int N) //宣告函數 | |
{ | |
int i, j, k; | |
FILE *out; | |
out = fopen("result", "w+"); | |
for (i = 0; i < N; i++) { //進行矩陣乘法運算 | |
for (k = 0; k < N; k++) { | |
for (j = 0; j < N; j++) | |
*(R + i * 99 + k) += *(M1 + i * 99 + j) * *(M2 + j * 99 + k); | |
} | |
} | |
for (i = 0; i < N; i++) { //印出結果矩陣 | |
for (j = 0; j < N; j++) | |
fprintf(out, "%.2f ", *(R + i * 99 + j)); | |
fprintf(out, "\n"); | |
} | |
fclose(out); | |
} | |
void inverse1(float *R, float *M, int N) //宣告函數 | |
{ | |
int x, y, k; | |
float temp; | |
FILE *out; | |
out = fopen("result", "w+"); | |
for (k = 0; k < N; k++) //設定單位矩陣 | |
*(R + k * 99 + k) = 1; | |
for (k = 0; k < N; k++) { | |
if ((IsMi0_ptr(M, k, N) == 1)) { //判斷某列是否全為0,若成立則反矩陣不存在。 | |
printf("This matrix has no inverse.\n"); | |
return; | |
} | |
if (*(M + k * 99 + k) == 0) { //若斜對角線之元素有0,則進行列交換。 | |
for (x = k + 1; x < N; x++) { | |
for (y = 0; y < N; y++) { | |
temp = *(M + k * 99 + y); | |
*(M + k * 99 + y) = *(M + x * 99 + y); | |
*(M + x * 99 + y) = temp; | |
temp = *(R + k * 99 + y); | |
*(R + k * 99 + y) = *(R + x * 99 + y); | |
*(R + x * 99 + y) = temp; | |
} | |
if (*(M + k * 99 + k) != 0) | |
break; | |
} | |
if (*(M + k * 99 + k) == 0) { //若無法交換至對角線無0,則反矩陣不存在。 | |
printf("This matrix has no inverse.\n"); | |
return; | |
} | |
} | |
temp = 1 / *(M + k * 99 + k); //進行高斯喬登消去法解反矩陣。 | |
for (y = 0; y < N; y++) { | |
*(M + k * 99 + y) *= temp; | |
*(R + k * 99 + y) *= temp; | |
} | |
for (x = 0; x < N; x++) { | |
if (x == k) | |
continue; | |
temp = *(M + x * 99 + k) / *(M + k * 99 + k); | |
for (y = 0; y < N; y++) { | |
*(M + x * 99 + y) -= temp * *(M + k * 99 + y); | |
*(R + x * 99 + y) -= temp * *(R + k * 99 + y); | |
} | |
} | |
temp = 1 / *(M + k * 99 + k); | |
for (y = 0; y < N; y++) { | |
*(M + k * 99 + y) *= temp; | |
*(R + k * 99 + y) *= temp; | |
} | |
} | |
for (x = 0; x < N; x++) { //印出反矩陣 | |
for (y = 0; y < N; y++) | |
fprintf(out, "%.2f ", *(R + x * 99 + y)); | |
fprintf(out, "\n"); | |
} | |
fclose(out); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int i, j, k, N, input, function; //宣告變數 | |
N = atoi(argv[1]); /*將尺寸存入N*/ | |
function = atoi(argv[2]); /*將算法對應數字存入function:1.add 2.multiplication 3.inverse 4.add1 5.multiplication1 6.inverse1*/ | |
input = atoi(argv[3]); /*將數字輸入方式對應數字存入input:1.隨機輸入 2.自行輸入*/ | |
float R[99][99], M1[99][99], M2[99][99], M[99][99]; //宣告陣列 | |
if (N > 99) //若尺寸超過則終止程式 | |
return; | |
for (i = 0; i < N; i++) { //矩陣初始化 | |
for (j = 0; j < N; j++) { | |
R[i][j] = 0; | |
M1[i][j] = 0; | |
M2[i][j] = 0; | |
M[i][j] = 0; | |
} | |
} | |
switch (input) { //選擇數字輸入方式 | |
case 1: if (function == 3 || function == 6) { //若選擇反矩陣運算函數,則使用M矩陣 | |
srand(time(NULL)); | |
for (i = 0; i < N; i++) { | |
for (j = 0; j < N; j++) | |
M[i][j] = rand() % 100; | |
} | |
} | |
srand(time(NULL)); //若選擇非反矩陣運算函數,則使用M1、M2矩陣 | |
for (i = 0; i < N; i++) { | |
for (j = 0; j < N; j++) { | |
M1[i][j] = rand() % 100; | |
M2[i][j] = rand() % 100; | |
} | |
} | |
break; | |
case 2: if (function == 3 || function == 6) { //若選擇反矩陣運算函數,則使用M矩陣 | |
printf("Please enter %d numbers for matrix M:\n", N * N); | |
for (i = 0; i < N; i++) { | |
for (j = 0; j < N; j++) | |
scanf("%f", &M[i][j]); | |
} | |
} | |
else { //若選擇非反矩陣運算函數,則使用M1、M2矩陣 | |
printf("Please enter %d numbers for matrix M1:\n", N * N); | |
for (i = 0; i < N; i++) { | |
for (j = 0; j < N; j++) | |
scanf("%f", &M1[i][j]); | |
} | |
printf("Please enter %d numbers for matrix M2:\n", N * N); | |
for (i = 0; i < N; i++) { | |
for (j = 0; j < N; j++) | |
scanf("%f", &M2[i][j]); | |
} | |
} | |
break; | |
} | |
switch (function) { //選擇運算函數並呼叫 | |
case 1: add(R, M1, M2, N); | |
break; | |
case 2: multiplication(R, M1, M2, N); | |
break; | |
case 3: inverse(R, M, N); | |
break; | |
case 4: add1(*R, *M1, *M2, N); | |
break; | |
case 5: multiplication1(*R, *M1, *M2, N); | |
break; | |
case 6: inverse1(*R, *M, N); | |
break; | |
} | |
return 0; | |
} |
沒有留言:
張貼留言