我已经实现了长数乘法,长数加法,长数减法和长数除法的功能。但是分工需要很长时间才能改进?这是我的代码:
/// removes unnecessary zeros
vector<int> zero(vector<int> a)
{
bool f=false;
int size=0;
for(int i=a.size()-1;i>=0;i--)
{
if(a[i]!=0)
{
f=true;
size=i;
break;
}
}
if(f)
{
vector<int> b(size+1);
for(int i=0;i<size+1;i++)
b[i]=a[size-i];
return b;
}
else
return a;
}
/// a+b
vector<int> sum(vector<int> a,vector<int> b)
{
if(a.size()>b.size())
{
vector<int> rez(3000);
int a_end=a.size()-1;
int remainder=0,k=0,ans;
for(int i=b.size()-1;i>=0;i--)
{
ans=a[a_end]+b[i]+remainder;
if(ans>9)
{
rez[k]=ans%10;
remainder=ans/10;
}
else
{
rez[k]=ans;
remainder=0;
}
k++;
a_end--;
}
int kk=k;
for(int i=a.size();i>kk;i--)
{
ans=a[a_end]+remainder;
if(ans>9)
{
rez[k]=ans%10;
remainder=ans/10;
}
else
{
rez[k]=ans;
remainder=0;
}
k++;
a_end--;
}
if(remainder!=0)
rez[k]=remainder;
return zero(rez);
}
else
{
vector<int> rez(3000);
int b_end=b.size()-1;
int remainder=0,k=0,ans;
for(int i=a.size()-1;i>=0;i--)
{
ans=b[b_end]+a[i]+remainder;
if(ans>9)
{
rez[k]=ans%10;
remainder=ans/10;
}
else
{
rez[k]=ans;
remainder=0;
}
k++;
b_end--;
}
int kk=k;
for(int i=b.size();i>kk;i--)
{
ans=b[b_end]+remainder;
if(ans>9)
{
rez[k]=ans%10;
remainder=ans/10;
}
else
{
rez[k]=ans;
remainder=0;
}
k++;
b_end--;
}
if(remainder!=0)
rez[k]=remainder;
return zero(rez);
}
}
/// a & b comparison
int compare(vector<int> a,vector<int> b)
{
if(a.size()>b.size())
return 1;
if(b.size()>a.size())
return 2;
int r=0;
for(int i=0;i<a.size();i++)
{
if(a[i]>b[i])
{
r=1;
break;
}
if(b[i]>a[i])
{
r=2;
break;
}
}
return r;
}
/// a-b
vector<int> subtraction(vector<int> a,vector<int> b)
{
vector<int> rez(1000);
int a_end=a.size()-1;
int k=0,ans;
for(int i=b.size()-1;i>=0;i--)
{
ans=a[a_end]-b[i];
if(ans<0)
{
rez[k]=10+ans;
a[a_end-1]--;
}
else
rez[k]=ans;
k++;
a_end--;
}
int kk=k;
for(int i=a.size();i>kk;i--)
{
ans=a[a_end];
if(ans<0)
{
rez[k]=10+ans;
a[a_end-1]--;
}
else
rez[k]=ans;
k++;
a_end--;
}
return zero(rez);
}
/// a div b
vector<int> div(vector<int> a,vector<int> b)
{
vector<int> rez(a.size());
rez=a;
int comp=-1;
vector<int> count(1000);
vector<int> one(1);
one[0]=1;
while(comp!=0 || comp!=2)
{
comp=compare(rez,b);
if(comp==0)
break;
rez=subtraction(rez,b);
count=sum(count,one);
}
count=sum(count,one);
return count;
}
答案 0 :(得分:2)
你的问题是你反复减法,这意味着你正在经历大量的大量迭代。这将导致非常糟糕的表现。
我在年初遇到了这个确切的问题(在一项单一的任务中)。我估计我原来的师(使用重复减法),需要大约100年才能完成。我实现了长除法(用手分割数字的方式相同),同样的计算需要大约5毫秒。这并不是一个糟糕的改进:)
不幸的是,多年来我没有使用过长的分裂,所以我忘记了怎么做。我很快找到了最专业的网站,试图重新学习并实施长期分工。我用过这个:http://www.coolmath4kids.com/long-division/long-division-lesson-1.html。是的,那是对的哈哈哈。该网站实际上帮助。我的算法在几个小时内完成了。
显然你不必使用那个网站,但你必须让你的算法更好。除了长期划分之外,还有更有效的方法可以做到这一点,但我发现长期划分可以在效率和易于实施之间取得良好的平衡。
答案 1 :(得分:1)
您使用慢速分割算法,并且存在快速分割算法http://en.wikipedia.org/wiki/Division_%28digital%29
答案 2 :(得分:1)
你的整个大数字实现可能很慢。作为一般规则,你应该使用base-2 16 (在32位机器中),也就是说,使用机器每个单词中的一半位,而不是使用base-10。 。
确保乘法不会溢出32位寄存器。开始实现{em>标准化大数字的normalize
函数(即对于每个存储的数字检查它是否溢出2 16 并且如果它确实应用了余数下一个数字)。由于数字范围较大,因此需要较少的内存,模数和除法运算较少。此外,基数为2的幂,模数和除法运算比使用基数为10的方法快得多。
然后可以基本上按元件执行所有操作。添加比两者中的较大者保留一位数,然后逐位添加,最后标准化结果。
在您的除法功能中,它会删除大量的矢量复制。目前,您正在创建一个3000 int
的向量,该向量在循环的每次迭代中被复制和处理,您可能需要考虑实现将修改向量而不是创建新向量的就地+=(vector,int)
操作矢量与所有复制。