題意: 實數的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指針變量, 並非數組指針。