【问题标题】:String multiplication: taking too much time字符串乘法:花费太多时间
【发布时间】:2019-03-23 14:35:21
【问题描述】:

我正在尝试制作一个有效的大数相乘程序,并提出了以下解决方案:-

#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(大约需要一秒钟)

对此的任何帮助表示赞赏。

编辑:如果有帮助,我已经添加了一些 cmets,基本上我正在做的是将一个数字的最后一位数字与另一个数字相乘(即 tmp = b[m-1] * a )并将其存储在一个字符串中(比如 c),用倒数第二个数字重复此操作( tmp = b[m-2] * a ),在末尾添加一个零字符串(处理十位)并使用上面定义的函数Addem(基本上是 c = c + tmp*10 )将其添加到字符串 c 中,重复该过程直到我们用完数字同时增加零的数量要添加到字符串的末尾。这应该需要 O(m*n)。

我有点怀疑这是由于使用 + 运算符或 std::erase 因为 std::erase 需要 O(n) 时间,但我不太确定。

【问题讨论】:

  • 对您提出的算法的解释将不胜感激。尝试以步骤的形式给出,然后描述你是如何实现每个步骤的。这样,我们可以更快地了解您的算法失败的地方
  • 添加了一些 cmets 和对我的逻辑的解释。

标签: string c++14


【解决方案1】:

在您的解决方案中,您正在计算每个数字乘法的临时字符串,并将其逐步添加到最终字符串中。 跳过它并切换到一个常见的可变结构(如 CFG 解决方案中的结果向量)并仅在正确的位置更新该结构。

随着数字的增长,温度会像

e.g. 100000*29990
    0
   90
  900
 9000
20000

每次 temp + c 操作,最后都会有很多零。对于所有这些,您仍在执行 0+0 或 0+(非零数)之类的操作,这些都是不必要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    相关资源
    最近更新 更多