【题目链接】
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1047
【解题思路】
这题借鉴了高精度加法里面的思想,加法部分详情请见链接
http://blog.csdn.net/jcr624/article/details/38128401
我们在手算乘法时,例如12*34,会先算12*4=48,再算0+48=48,接着算12*3=36,将36左移一位变成360,接着将48+360=408,这样乘法就算完成了。以下的核心代码正是模拟了手算这一部分。
bigNumber y;//保存乘法结果
for (int i = 0; i < len; i ++)//左乘数遍历整数位
{
bigNumber mult;//保存左乘数当前位与右乘数相乘的结果
int temp;
for (int j = 0, a = 0; a || j < x.len; j ++)//右乘数遍历整数位
{
int k = i+j;//k为两者相乘的结果应存放的位置,如两个乘数第0位和第0位相乘,结果应该在y的第0位
temp = a+num[i]*x.num[j];
mult.num[k ++] = temp % 10;
a = temp/10;
mult.len = k;
}
y = y+mult;//模拟手算过程,右乘数遍历结束后执行一次加法,直到左乘数遍历结束
}
跟高精度加法类似,乘法只是将运算符号由+换成了*,进位原理与加法一致,通过O(n^2)的时间复杂度,遍历左乘数和右乘数数位,乘加交替即可得出答案。但是该题目中,需要注意这样的一种特殊情况:
111111*0
如果仅是按照以上算法,会得到000000这样的错误结果,虽然值大小一样,但是输出对格式也是有要求的,这就需要我们去除前面多余的0。
【代码】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int MAX(int a, int b)
{
return a > b ? a : b;
}
typedef struct bigNumber
{
int num[800];
int len;
bigNumber()
{
memset(num, 0, sizeof (num));
len = 0;
}
bigNumber operator= (const bigNumber x)
{
len = x.len;
for (int i = 0; i < len; i ++)
{
num[i] = x.num[i];
len = x.len;
}
return *this;
}
bigNumber operator+ (const bigNumber x) const
{
bigNumber y;
int max_len = MAX(len, x.len);
for (int i = 0, a = 0; a || i < max_len; i ++)
{
int temp = a;
if (i < len) temp = temp+num[i];
if (i < x.len) temp = temp+x.num[i];
y.num[y.len ++] = temp%10;
a = temp/10;
}
return y;
}
bigNumber operator* (const bigNumber x) const
{
bigNumber y;//保存乘法结果
for (int i = 0; i < len; i ++)//左乘数遍历整数位
{
bigNumber mult;//保存左乘数当前位与右乘数相乘的结果
int temp;
for (int j = 0, a = 0; a || j < x.len; j ++)//右乘数遍历整数位
{
int k = i+j;//k为两者相乘的结果应存放的位置,如两个乘数第0位和第0位相乘,结果应该在y的第0位
temp = a+num[i]*x.num[j];
mult.num[k ++] = temp % 10;
a = temp/10;
mult.len = k;
}
y = y+mult;//模拟手算过程,右乘数遍历结束后执行一次加法,直到左乘数遍历结束
}
int flag = 0;
for (int i = 0; i < y.len; i ++)
{
flag = flag | y.num[i];//整数位当中只有有一位不为0,可断定这个整数肯定不是0
}
if (flag == 0)
y.len = 1;//去除前导0
return y;
}
void input(char *x)//将字符串逆转,保存在整型数组里
{
len = strlen(x);
for (int i = 0; i < len; i ++)
{
num[i] = x[len-1-i]-'0';
}
}
void output()//逐位输出结果,注意这里的数组保存是逆序的
{
for (int i = len-1; i >= 0; i --)
{
printf("%d", num[i]);
}
}
}bigNumber;
int main()
{
char str1[300], str2[300];
while (~scanf("%s %s", str1, str2))
{
bigNumber a, b, c;
a.input(str1);
b.input(str2);
c = a*b;
c.output();
printf("\n");
}
return 0;
}