NUTN CH7 P3

首次架設靜態網站,如有疏失,還請多多包涵。歡迎來信zhuastor@gmail.com

解題心得

南大的程式設計作業,給我的感覺是很要求格式,所以往往要把自己的解法跟題目指示的操作融合在一起。
這一題我寫了快四個小時,coding以外的時間都在查詢一些技巧在c語言中的使用方式,以及思考如何配合題目的函式。
除此之外,我在規劃輸入的時候卡了許久,題目中有些細節使我不太敢草率下手。

解題想法

首先整理結束條件以及輸入操作失敗條件,題目沒有詳細給(我猜是要訓練我們思考問題的全面程度)。
再來就是比較麻煩的輸入了,我選擇粗暴地用字元來讀,這個寫法還蠻考驗個人的實作能力。
以下解釋三個函式:
fget_point_mass(回傳一個整數):輸入的同時賦予location二維陣列以及mass一維陣列的元素數值,並且透過換行來判斷當前質點的輸入是否正確,是否達到終止條件或者輸入操作失敗條件。
center_grav(回傳名稱為point_3D的自訂struct):就計算C。
fwrite_point_mass(void):就輸出資料到檔案。
大方向就這樣,邏輯細節都有寫註解(數字關係請自己試著觀察),大家哪個部分有問題再細看就好,沒看過的用法也請自己試著查詢。

AC code

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>

struct point_3D{
	double x,y,z;
};

int fget_point_mass(FILE* inp, int (*location), int mass[], int* n);
point_3D center_grav(int (*location), int mass[], int n);
void fwrite_point_mass(FILE* oup, int (*location), int mass[], int n, point_3D center_gravity);



// input operation failed : 
//1.the num of point mass more than n
//2.a point mass is incomplete

//根據題目的敘述,我的理解是:一個質點系統有可能出現n個以下的質點數量


int main() {

	FILE* inp;
	FILE* oup;
	int location[15][3];
	int mass[15];//index從1開始
	int n;
	char endl;

	if (!(inp = fopen("C:\\File123\\input.txt", "r"))) {
		printf("input file open failed\n");
	}
	else {
		printf("input file open\n");
	}
	oup = fopen("C:\\File123\\output.txt", "w");

	//假設一定有數據,以每次輸入的n作為終結上一個質點系統的條件
	fscanf(inp, "%d%c", &n, &endl);

	while (true) {//質點系統的迴圈
		int actual_n;
		point_3D center_gravity;

		actual_n=fget_point_mass(inp,(int *)location,mass,&n);

		if (actual_n == -1) {
			printf("input_operation_failed\n"); break;
		}
		else {

			if (actual_n == -2) {
				center_gravity = center_grav((int*)location, mass, n);

				fwrite_point_mass(oup, (int*)location, mass, n, center_gravity);
			}
			else {
				center_gravity = center_grav((int*)location, mass, actual_n);

				fwrite_point_mass(oup, (int*)location, mass, actual_n, center_gravity);
			}
		}
		if (actual_n == -2) {
			printf("It is end of file\n"); break;
		}
	}


	fclose(inp);
	fclose(oup);

	system("pause");
	return 0;
}
//
// 
//main function end
//
//
int fget_point_mass(FILE* inp, int (*location), int mass[], int* n) {
	int now = -1, index = 1, row_index = 0;
	char now_char;
	while (true) {//質點的迴圈
		row_index = 0;//當前是新的質點
		bool now_is_negative = false;
		while (fscanf(inp, "%c", &now_char) && now_char!='\n') {//輸入字元直到換行
			if ((int)now_char >= 48 && (int)now_char <= 57) {//當前字元若是數字
				if (now == -1) {//如果目前now沒有數字
					row_index++; now = 0;
					now = now * 10 + ((int)now_char - 48);
				}
				else {
					now = now * 10 + ((int)now_char - 48);
				}
			}
			else if (now_char == '-')now_is_negative = true;
			else {//當前字元若不是數字
				if (now != -1) {//如果now有數字,要將他讀入
					if (now_is_negative)now *= -1;
					(*(location + (index-1) * 3 + row_index-1)) = now;
					now_is_negative = false;
					now = -1;//初始化
				}
			}
		}
		if (row_index == 1) {//如果只出現一個數字,可是卻換行了,這代表達到質點系統的終結條件(即下一個質點系統的n)
			*n = now;//終結條件
			return index-1;
		}
		else if (row_index == 4) {//如果換行了,且該行總共輸入四個數字,第四個數字不會被前面的while讀入 
			if (now_is_negative)now *= -1;
			mass[index] = now;
			now = -1;//初始化
		}
		else if (row_index == 0) {
			*n = index-1;
			return -2;
		}
		else {//不規則的輸入,一個質點沒有輸入四個數字,就是第二個輸入操作錯誤條件
			return -1;
		}
		if (index > *n) {//當符合輸入操作錯誤的第一個條件
			return -1;
		}
		index++;//往下一個質點
	}
}
point_3D center_grav(int (*location), int mass[], int n) {
	double sumx=0,sumy=0,sumz=0;
	int m = 0;
	point_3D ans;
	for (int x = 1; x <= n; x++)m += mass[x];
	for (int x = 0; x < n; x++) {
		sumx += *(location + x * 3 + 0) * mass[x+1];
		sumy += *(location + x * 3 + 1) * mass[x+1];
		sumz += *(location + x * 3 + 2) * mass[x+1];
	}
	
	printf("%.2f %.2f %.2f\n", sumx, sumy, sumz);
	sumx /= (double)m; sumy /= (double)m; sumz /= (double)m;
	printf("%.2f %.2f %.2f\n", sumx, sumy, sumz);
	ans.x = sumx; ans.y = sumy; ans.z = sumz;
	return ans;
}
void fwrite_point_mass(FILE* oup, int(*location), int mass[], int n, point_3D center_gravity) {
	fprintf(oup, "location-------\n");
	for (int x = 0; x < n; x++) {
		for (int y = 0; y < 3; y++) {
			fprintf(oup, "%d ", (*(location + x * 3 + y)));
		}fprintf(oup, "\n");
	}
	fprintf(oup, "mass-----------\n");
	for (int x = 1; x <=n; x++) {
		fprintf(oup,"%d\n", mass[x]);
	}
	fprintf(oup, "n--------------\n");
	fprintf(oup, "%d\n", n);
	fprintf(oup, "center_gravity-\n");
	fprintf(oup, "(%.2f %.2f %.2f)\n", center_gravity.x, center_gravity.y, center_gravity.z);
	fprintf(oup, "\n\n");
}