北大OJ——求幂算法解析(1001)

本文详细解析了北大OJ中的求幂算法,涉及将高精度数值用字符串存储,去除小数点,模拟乘法运算,以及添加小数点的步骤。通过举例说明了每个阶段的操作,并介绍了代码实现过程。
摘要由CSDN通过智能技术生成

本文章只代表作者自己的思路,如有不对,欢迎各位大佬指导,博主还是个菜鸟,博文只做笔记使用

题目描述:

此图像的alt属性为空;文件名为image-430-1024x313.png

 

题目样本:

此图像的alt属性为空;文件名为image-431-1024x381.png

 

思路:

  • 常见的int,double,long已经满足不了那么高精度的数值
  • 我们可以用字符串存入字符数组中,再进行计算
  • 例如1.23和1.23相乘
  • 从字符串的输入,从小数点位置判断出小数点后的位数,这里是2位
  • 在字符串中去掉小数点,这里是123
  • 然后取数依次相乘,产生的进位相加,根据位置再错位相加,这里是
  • 123
  • 0246
  • 00369
  • 得到字符串是15129
  • 然后两个乘数的小数点位数和是4,所以结果的小数点也移动4位
  • 则结果是1.5129
  • 乘法运算就完成了,因为是字符串,所以位数可以特别长
  • 特别注意:首位相乘产生的进位要单独存放,因为每一位数在[0,9]之间
  • 最大计算值为81,,只有一个进位

然后看下代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
void rmpoint(char[], int*);
void chen(char[], char[]);
void addpoint(char[], char[], int);
int main()
{
	char n1[7], n2[410], n3[410];
	int a, p, i;
	/*输入基数和指数*/
	while (scanf("%s %d", n1, &a) != EOF)
	{
		rmpoint(n1, &p);/*将基数和指数存入字符串*/
		strcpy(n2, n1);
		for (i = 0; i < a - 1; i++)
		{
			chen(n1, n2);
		}
		p = p * a;
		if (p != 0)
		{
			addpoint(n2, n3, p);
		}
		printf("%s\n", n3);
	}
	return 0;
}
void rmpoint(char a[], int* c)
{
	int i, j, p, c1;
	c1 = 0;
	//char b[205];
	p = strlen(a);
	for (i = 0, j = 0; i < p; i++)
	{
		if (a[i] == '.')
		{
			c1 = p - 1 - i;
			continue;
		}
		a[j] = a[i];
		j++;
	}

	*c = c1;
	a[j] = 0;
}
void chen(char a[], char b[])
{
	int c[410] = { 0 };
	int i, j, sum, k, k1;
	k = 409;
	k1 = 409;
	for (i = strlen(a) - 1; i >= 0; i--)
	{
		for (j = strlen(b) - 1; j >= 0; j--, k--)
		{
			sum = (a[i] - '0') * (b[j] - '0') + c[k];
			c[k - 1] = c[k - 1] + sum / 10;
			c[k] = sum % 10;
		}
		k = --k1;
	}
	for (i = 0; i < 410; i++)
	{
		if (c[i] != 0)
		{
			break;
		}
	}
	for (j = i, i = 0; j < 410; i++, j++)
	{
		b[i] = c[j] + '0';
	}
	b[i] = 0;
}
void addpoint(char a[], char b[], int p)
{
	int i, j, p1, p2, j1, min;
	p2 = 0;
	p1 = strlen(a);
	if (p1 >= p)
	{
		p = p1 - p;
		for (i = p1 - 1; i >= 0; i--)
		{
			if (a[i] != '0')
			{
				break;
			}
			p2++;
		}
		if (p1 - p2 < p)
		{
			min = p;
		}
		else
		{
			min = p1 - p2;
		}
		for (i = 0, j = 0; i < min; i++, j++)
		{
			if (p == i)
			{
				b[j] = '.';
				i--;
				p--;
				continue;
			}
			b[j] = a[i];
		}
		b[j] = 0;
	}
	else
	{
		b[0] = '.';
		p = p - p1;
		for (i = p1 - 1,j1 = 0; p1 >= 0; i--)
		{
			if (a[i] != '0')
			{
				break;
			}
			j1++;
		}
		for (i = 1, j = 0; j < p; j++, i++)
		{
			b[i] = '0';
		}

		for (j = 0; j < p1 - j1; i++, j++)
		{
			b[i] = a[j];
		}
		b[i] = 0;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值