#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include <string.h> //strlen(x)必要,而不是<string>
using namespace std;
int main()
{
char x[99999];
char y[99999];
char z[99999];//存放每次乘法结果
char z_all[99999]; //存放加起来的结果
char big[99999];//存放x[]和y[]更大的那个数组 ,相当于列式计算的上面那个数
char small[99999];//存放x[]和y[]更小的那个数组 ,相当于列式计算的下面那个数
int multi=0;//2个数相乘得到的
int count=0;//乘法进位的数
int length=0;//用于计算z[]的长度
int length_all=0; //用于计算z_all[]的长度,很难搞,因为ascii0代表为\0,所以strlen(z_all)没用,length_all=length或者length+1或-1
int plus=0;//2个数相加得到的
int count_z=0;//加法进位的数
scanf("%s",&x);
scanf("%s",&y);
int x_length=strlen(x);
int big_length=0;//记录x_length和y_length更大的长度为
int y_length=strlen(y);
int small_length=0;//记录x_length和y_length更小的长度为
//1,判断x[]和y[]谁更长,得到长度,并把更长的放入big[],更短的放入small[]
//2,每一位都-48,才可以开始计算。
if(x_length>y_length)
{
big_length=x_length;
small_length=y_length;
for(int i=0;i<(big_length);i++)
{
big[i]=x[i]-48;
if(i<y_length)
small[i]=y[i]-48;
else small[i]=0;
}
}
else
{
big_length=y_length;
small_length=x_length;
for(int i=0;i<(big_length);i++)
{
big[i]=y[i]-48;
if(i<x_length)
small[i]=x[i]-48;
else small[i]=0;
}
}
//字符串逆转strrev(),不能用这个函数,和strlen()一样,碰ascii0结束
//strrev(big);
int num=big_length/2;
int first_num=0;//执行字符串逆转的
for(int i=0;i<num;i++)
{
first_num=big[i];
big[i]=big[big_length-1-i];
big[big_length-1-i]=first_num;
}
//strrev(small);
num=small_length/2;
for(int i=0;i<num;i++)
{
first_num=small[i];
small[i]=small[small_length-1-i];
small[small_length-1-i]=first_num;
}
//--------------------计算每次结果,并执行加法,得到总结果
for(int i=0;i<small_length;i++)
{
memset(z, 0, sizeof(z));//用完数组一定要记得情空
count=0;
length=0;
for(int j=0;j<big_length;j++)
{
multi=small[i]*big[j]+count;
if(multi<10)
{
count=0;
}
else count=multi/10;
z[j]=multi%10;
length++;
//每次运算结果的第一位可能需要进位
if(j==big_length-1)
{
if(multi>=10)
{
length++;
z[j+1]=multi/10;
}
count=0; //运算完了之后进位为0
}
}
//逆转每次运算结果再加上根据正在计算small[]中第几个数决定末尾的0,真正的每次运算结果
//strrev(z);//字符串逆转
num=length/2;
for(int m=0;m<num;m++)
{
first_num=z[m];
z[m]=z[length-1-m];
z[length-1-m]=first_num;
}
//根据正在计算small[]中第几个数决定末尾的0,真正的每次运算结果
for(int m=0;m<i;m++)
{
z[length]=0;
length++;
}
//在每次 执行z_all[]和z[] 的加法 之前先对z_all[]补充到和z[]一样的位数
//可能补充1位,可能补充2位
if(length_all==length)
;
else
{
//1 是 -1,2是+0,3是+1 ,4是 +2,相差2
//观察得到 length-length_all-2 是
for(int m=length+(length-length_all-2);m>=length-length_all;m--)
{
z_all[m]=z_all[m-(length-length_all)];
}
for(int m=0;m<length-length_all;m++)
{
z_all[m]=0;
}
length_all=length;
}
//加起来存放在z_all[],执行z_all[]和z[] 的加法
for(int m=(length-1);m>=0;m--)
{
plus=z[m]+z_all[m]+count_z;
if(plus>=10)
{
count_z=1;
z_all[m]=plus%10;
//每次运算结果的第一位可能需要进位
if(m==0)
{
count_z=0;
//必须这样写,不然strlen()以\0结束,而ascii的0就是\0
length_all=length+1;
for(int n=length;n>0;n--)
{
z_all[n]=z_all[n-1];
}
z_all[0]=1;
}
}
else
{
z_all[m]=plus;
count_z=0;
}
}
}
//--------------------得到总结果
//还原成char[],才可以用字符串%s显示出来,不然可能要一个一个%d输出
for(int i=0;i<length_all;i++)
{
z_all[i]+=48;
}
printf("总结果为%s",z_all);
system("pause");
}
190行的代码,测试用例
99999
888
答案是88799112
456456
123
答案是56144088
测试输入的2个大数含有0,导致z_all[]有0,z[]有0
5002
1005
答案是5027010
测试先输入的数更小
5153135
561523152315615615614
答案是2893604609507929875367049890
执行加法的时候,z_all[]肯定小于等于z[]的位数,但是可能相差2位
测试z_all[]和z[]相差2位会不会出错
890749640310
50438001
答案44927631248705420310
测试很大的数
90651132051212022320006511320512120223200132051212022313205121202232000651132051212013205121202232000651132051212013205121202232000651132051212013205121202232000651132051212020006511320512121320512120223200065113205121200223200065113205121201320512120132051212022320006511320512120132051212022320006511320512120
90651132051212022320006511320512120223200132051212022313205121202232000651132051212013205121202232000651132051212013205121202232000651132051212013205121202232000651132051212020006511320512121320512120223200065113205121200223200065113205121201320512120132051212022320006511320512120132051212022320006511320512120
答案是
8217627742166279593258384227255322134089168057783095489827406231962126915594425136982130897336827272053686532782672814722755608909707178267744737424004508273738713256092706803266393688426607267974586188598208659424356181871486133193036707046839862429341995222708292917387307560071705279510878182313569177763680001920799585684429461042518936481023593237602722809931476763334431426660612680265603460144823480818435663628168450038546990715014132411802891692469338365699322791894396940981129039967003179268156321618886806960655095730601018201634939432173224868109964974975399259786821141967502182478768938331611554659066894400
1,strlen()和strrev()不能对char[]存放数字0进行操作,因为ascii0就是字符\0,需要自己实现strlen()和strrev()