题意: 实数的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指针变量, 并非数组指针。