模拟字符串相乘(大数运算)

1. 题目:模拟字符串相乘

2. 思路:

平时计算乘法列竖式有两种方式

第一种方式,比如123乘以456,可以是123的每一位依次乘以6,在乘以5,再乘以4。错位再相加
在这里插入图片描述
第二种方式,也可以是456的每一位依次乘以3,在乘以2,再乘以1。错位再相加
在这里插入图片描述
其实是可以模拟这种列竖式的计算。假如我们把进位放在最后处理。

模拟第一种方式列竖式:
在这里插入图片描述
模拟第二种方式列竖式:
在这里插入图片描述
而使用两层for循环就能很好的模拟这种情况

for(int i=a.size()-1;i>=0;i--)
{
    for(int j=b.size()-1;j>=0;j--)
   {
     c[i+j]+=a[i]*b[j]; //必须为+=因为后续还有数据会加上来
   }
}

举个例子:3固定不变,6,5,4依次去乘以3(从个位开始),得到18,15,12。放在c数组的下标为4,3,2处。

下面开始验证:

外层循环i对应的第一次循环结束
在这里插入图片描述
外层循环i对应的第二次循环结束
在这里插入图片描述
外层循环对应的第三次循环结束
在这里插入图片描述
最终c数组里就面就存储了,乘好的,但是没有进位的数据
在这里插入图片描述
接下来模拟进位:

原本想着全进位之后,在转成字符串,但是看到一种很巧妙的解法。

先定义一个空串,他保存最终转换的结果string ans;

定义进位符号 int flag=0;

for(int i=c.size()-1;i>=0;i++)

{

//原来的数据加上进位后的数据就是真正的数据了

a[i]+=flag;

//进位完之后的数据

char a=a[i]%10-'0';

//很巧妙,c就是进位完之后的数据,直接+到字符串后面,不用像我们之前那样全进位,在转成字符串

ans=a+ans;

//进位要用的数据,例如18的前一个数据就要+1,27的前一个数据+2

flag=a[i]/10;

}

假如c[0]位置算完之后也有进位,但由于循环走到c[0]退出,无法对它进行处理。

例如 9*9,按我们的玩法模拟出就是1,8还在flag里,结果循环退出了。

那么就对flag进行判断,把它加上去。

while(flag)

{

char a=flag-'0';

ans=a+ans;

}

在这里插入图片描述

还有一种情况,这种测试用例没考虑到

999*0 这时转换到字符串就会成"000",但是当多个0的时候我们只需要一个。所以再加一条语句

while(ans.size()>0 && ans[0]=='0')

{

​     ans.erase(ans.begin());

}

return ans;

3. 完整代码

class Solution {
public:
    string multiply(string num1, string num2) {
        vector<int> a(num1.size(), 0);
		vector<int> b(num2.size(), 0);
		vector<int> c(num1.size() + num2.size()-1, 0);
      
       for(int i=0;i<num1.size();i++)
       {
          a[i]=num1[i]-'0';
       }
       for(int i=0;i<num2.size();i++)
       {
           b[i]=num2[i]-'0';
       }
       for(int i=a.size()-1;i>=0;i--)
       {
           for(int j=b.size()-1;j>=0;j--)
           {
               c[i+j]+=a[i]*b[j];
           }
       }
        int flag = 0;
		string ans;
		for (int i = c.size() - 1; i >= 0; i--)
		{
			c[i] = c[i] + flag;
			char a = c[i] % 10 + '0';
			ans = a + ans;
			flag = c[i] / 10;
		}
        while(flag)
        {
            char a=flag+'0';
            ans=a+ans;
            flag/=10;
        }
        while(ans.size()>1 && ans[0]=='0')
        {
            ans.erase(ans.begin());
        }

       return ans;
    }
};
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值