我正在尝试制作一个有效的程序来乘大数,并提出了以下解决方案:-
#include <iostream>
using namespace std;
string Addem(string a,string b) // To add two large numbers,only for +ve numbers
{
string c;
int n=a.size(),m=b.size();
if(m>n)
{
swap(n,m);
swap(a,b);
}
for(int i=0; i<n-m; i++) // adding zeros to make lengths of both string equal.
b='0'+b;
int carry=0,curr=0;
for(int i=n-1; i>-1; i--)
{
curr=a[i]-'0'+b[i]-'0'+carry; //basic school math to find sum, using
carry=curr/10; //two variables to find sum of each place individually
curr=curr%10; //and passing carry to the next position.
c=(char)(curr+'0')+c;
if(i==0 && carry)
{
c=(char)(carry+'0')+c;
}
}
while(c[0]=='0' && c.size()!=1) //removing any leading zeros
c.erase(0,1);
return c;
}
string Multiplyem(string a,string b) // To multiply two large numbers.
{
bool sign=1;
if( (a[0]=='-' && b[0]=='-') || (a[0]!='-' && b[0]!='-') )
sign=0;
if(a[0]=='-')
a.erase(0,1); //taking care of sign.
if(b[0]=='-')
b.erase(0,1);
if(a=="0" || b=="0")
return "0";
string c;
int curr=0,carry=0;
int n=a.size(),m=b.size();
for(int i=m-1; i>-1; i--)
{
string tmp; //string to store result of a*(current digit of b)
for(int j=n-1; j>-1; j--)
{
curr=carry+(b[i]-'0')*(a[j]-'0'); //scroll down for this,explained
carry=curr/10; //the logic for this under EDIT
curr=curr%10;
tmp=(char)(curr+'0')+tmp;
if(j==0 && carry)
{
tmp=(char)(carry+'0')+tmp;
}
}
for(int j=m-1; j>i; j--) //adding zeros take care of number positions
tmp+='0';
c=Addem(tmp,c); //adding tmp to c
carry=0,curr=0;
}
while(c[0]=='0' && c.size()!=1) // removing any leading zeros (if any)
c.erase(0,1);
if(sign==1 && c!="0") //adding sign (if reqired)
c='-'+c;
return c;
}
int main()
{
string a,b;
cin>>a>>b;
cout<<"Multiplication = "<<Multiplyem(a,b)<<" \n \n";
}
据我所知,复杂度是O(m * n),但是,当我实际尝试时,它花费了太多时间。 我已经在看似相同的复杂性的另一代码上试用了相同的测试用例,但是该代码用时为0.04秒。而我的需要1.02秒。
GFG solution(耗时0.04秒)
My solution(大约需要一秒钟)
对此有任何帮助。
编辑:如果有帮助,我已经添加了一些注释,基本上我正在做的是将一个数字的最后一位乘以另一个数字(即
tmp = b [m-1] * a)并将其存储在字符串中(例如c),并使用倒数第二个数字(tmp = b [m-2] * a)重复此操作,并在末尾添加零字符串(照顾十位),并使用上面定义的函数Addem
将其添加到字符串c中(基本上是c = c + tmp * 10),重复此过程,直到数字用完,同时增加数字要在字符串末尾添加的零。这应该是O(m * n)。
我有点怀疑这是由于使用+运算符或std :: erase,因为std :: erase需要O(n)时间,但我不太确定。
答案 0 :(得分:1)
在您的解决方案中,您正在为每个数字乘法计算临时字符串,并将其增量累加到最终字符串中。 跳过它,切换到通用的可变结构(例如CFG解决方案中的结果向量),并仅在正确的位置继续更新该结构。
随着数字的增长,温度会像
e.g. 100000*29990
0
90
900
9000
20000
对于每一个temp + c操作,最后都会有很多零。对于所有这些,您仍在执行不必要的操作,例如0 + 0或0+(非零数字)。