POJ1001 高精度

題意: 實數的n次冪。如果小於0,小數點前的0不用輸出。

算法: 1.輸入(底數當做字符串來處理, 指數直接int輸入)

     2.記錄小數點位數,刪除小數點

     3.將底數由char[] ——>int[],並且顛倒數字順序。如:“95.123”——>{3, 2, 1, 5, 9}.同時獲取底數的位數

     4.計算n次冪

     5.輸出。

    細化: 1、2、3步沒有什麼要注意的。  主要在第四步:

 4.a.要注意是進行n-1次乘法。 

    b.存在數組裏的數可能會溢出, 及時做進位處理

    c.每次乘積的結果要重新計算它的位數。 我一開始天真的以爲每次位數增加 (bits_lead - 1)位, 一直得不到結果。

5.a.輸出時注意要去除前綴零 和 後綴零

    b.小數點根據一開始記錄的小數點位數來輸出


代碼:

#include <stdio.h>
#include <string.h>

#define MAX_OUT_BITS 100
#define MAX_IN_BITS 30

int bits_lead, bits_zero_point,int_lead[MAX_IN_BITS];
int result[MAX_OUT_BITS], tmp_result[MAX_OUT_BITS];
char ch_lead[MAX_IN_BITS];
int int_index;

int toDigit(void);		//轉換成int的函數
void toPow(void);
void toPrint(void);
void toTen(int *);		//進位函數
void toMultiply(int *, int *);

int main() {
	char *p;

	while (scanf("%s%d", ch_lead, &int_index) != EOF) {

		for (p = ch_lead; *p != '.'; p++) {
		}
		bits_zero_point = strlen(p) - 1; 
		strcpy(p, p + 1);			//delete '.'

		bits_lead = toDigit();
		toPow();
		toPrint();
	}

	return 0;
}

/****************************************************************************
 * toDigit(): num(char) to num(int) and transpos num sort
 ***************************************************************************/
int toDigit(void) {
	int bits;
	int i, j;
	
	memset(int_lead, 0, sizeof(int_lead));
	bits = strlen(ch_lead);
	for (i = 0, j = bits - 1; i < bits; i++, j--) {
		int_lead[j] = (int)(ch_lead[i] - '0');
	}

	return bits;
}

/************************************************************************
 * toPow():
 * *********************************************************************/
void toPow(void) {
	int i, j, k, l;
	int change[MAX_OUT_BITS];

	int_index--;			//進行int_index次乘法

	memset(result, 0, sizeof(result));
	for (i = 0; i < bits_lead; i++) {
		result[i] = int_lead[i];
	}

	for (i = 0; i < int_index; i++){

		//translate result to change
		for (j = 0; j < MAX_OUT_BITS; j++) {
			change[j] = result[j];
		}
		
		toMultiply(change, int_lead);
		toTen(result);				//及時進位
	}
}

/************************************************************************
 * toTen():
 * *********************************************************************/
void toTen(int *num) { 
	int tmp;

	for (int i = 0; i < MAX_OUT_BITS; i++) {
		tmp = num[i] / 10;
		num[i] = num[i] % 10;
		num[i + 1] += tmp;
	}
}

/*************************************************************************
 * toMultiply():
 * **********************************************************************/
void toMultiply(int *change, int *lead) {
	int chg_bits;

	//get chg_bits(重新統計位數)
	for (int i = MAX_OUT_BITS - 1; i >= 0; i--) {
		if (change[i] != 0) {
			chg_bits = i + 1;
			break;
		}
	}

	memset(result, 0, sizeof(result));	

	for (int i = 0; i < chg_bits; i++) {
		for (int j = 0; j < bits_lead; j++) {
			result[i + j] += change[i] * lead[j];
		}
	}
}




/*************************************************************************
 * toPrint()
 ************************************************************************/
void toPrint(void) {
	int mark_head = 0, mark_tail = 0, i;
	int num_point;
	num_point = bits_zero_point * (int_index + 1);

	//去除後綴零
	for (i = 0; i < MAX_OUT_BITS; i++) {
		if (result[i] != 0) {
			mark_tail = i;
			break;
		}
	}
	for (i = (MAX_OUT_BITS - 1); i >= mark_tail ; i--) {
		if (result[i] != 0) {			//去除前綴零
			mark_head = 1;
		}

		if (i == num_point - 1){		//打印小數點
			printf(".");
			mark_head = 1;
		}

		if (mark_head == 1) {
			printf("%d", result[i]);
		}

	}

	printf("\n");

}


教訓:1.算法的核心部分(toPow())寫得不清不楚就直接開始敲代碼。 結果各種錯。

   2.不踏實, 太急功近利。 不過到最後一天表現不錯, 很有耐心。(這道題我卡了3天, toPow()函數。快哭了)。其實耐心一點,第一天就能解決掉的。

   3.少用全局變量。 函數接口化。 這是很值得去做的。 重寫toPow(), 加入一個toMultiply(int *, int *, int *)函數。 result[] 已經定義爲全局變量了, 但是我卻把它作爲函數參數, 在函數中用memset(result, 0, sizeof(result)); 結果只有result[0] 被清爲零。 因爲這裏的result是局部int指針變量, 並非數組指針。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章