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指针变量, 并非数组指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值