• 43. 字符串相乘


    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

    示例 1:

    输入: num1 = "2", num2 = "3"
    输出: "6"
    示例 2:

    输入: num1 = "123", num2 = "456"
    输出: "56088"
    说明:

    num1 和 num2 的长度小于110。
    num1 和 num2 只包含数字 0-9。
    num1 和 num2 均不以零开头,除非是数字 0 本身。
    不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

    #include<iostream>
    #include<stack>
    #include<algorithm>
    #include<string>
    #include<vector>
    using namespace std;
    /*
       8 9  <- num2
       7 6  <- num1
    -------
       5 4
      4 8
      6 3
    5 6
    -------
    6 7 6 4
    两数相乘得到的乘积的长度其实其实不会超过两个数字的长度之和,
    若 num1 长度为m,num2 长度为n,则 num1 x num2 的长度不会超过 m+n,
    还有就是要明白乘的时候为什么要错位,比如6乘8得到的 48 
    为啥要跟6乘9得到的 54 错位相加,因为8是十位上的数字,
    其本身相当于80,所以错开的一位实际上末尾需要补的0。
    还有一点需要观察出来的就是,num1 和 num2 中任意位置的两个数字相乘,
    得到的两位数在最终结果中的位置是确定的,
    比如 num1 中位置为i的数字乘以 num2 中位置为j的数字,
    那么得到的两位数字的位置为 i+j 和 i+j+1,明白了这些后,
    就可以进行错位相加了,累加出最终的结果。由于要从个位上开始相乘,
    所以从 num1 和 num2 字符串的尾部开始往前遍历,分别提取出对应位置上的字符,
    将其转为整型后相乘。然后确定相乘后的两位数所在的位置 p1 和 p2,
    由于 p2 相较于 p1 是低位,所以将得到的两位数 mul 先加到 p2 位置上去,
    这样可能会导致 p2 位上的数字大于9,所以将十位上的数字要加到高位 p1 上去,
    只将余数留在 p2 位置,这样每个位上的数字都变成一位。
    保存在vals里需要去掉前面多余的0
    */
    
    class Solution {
    public:
    	string multiply(string num1, string num2) 
    	{
    		int m = num1.size(), n = num2.size();
    		string vals(m + n,'0');//初始化大小m+n
    		for (int i = m - 1; i >= 0; i--) 
    		{
    			for (int j = n - 1; j >= 0;j--) //从后向前
    			{
    				int mul = (num1[i] - '0') * (num2[j] - '0');
    				int p1 = i + j, p2 = i + j + 1;
    				int sum = mul + (vals[p2] - '0');//累加之前的结果
    				vals[p1] += sum / 10 ;
    				vals[p2] = sum % 10 + '0';
    			}
    		}
    		for (int i = 0; i < m + n; i++)
    		{
    
    			if (vals[i] != '0') return vals.substr(i);//去掉前面多余的0
    		}
    		return "0";
    	}
    };
    int main()
    {
    	string s1;
    	string s2;
    	string ans;
    	getline(cin, s1);
    	getline(cin, s2);
    	ans = Solution().multiply(s1,s2);
    	cout << ans<<endl;
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    java 笔记(2) 接口作为引用数据类型
    linux 笔记(5)让vi或vim显示行数和不显示行数
    linux 笔记(4)Ubuntu 使用时vi编辑器时,不能使用backspace键来进行退格或者不能正常使用
    linux 笔记(3)sudo passwd 设置root用户的密码
    matlab笔记(1) 元胞结构cell2mat和num2cell
    linux 笔记(2) 目录直接强行删除rm -rf *(删除当前目录所有的内容)
    linux 笔记(1) ctrl+c,ctrl+z,ctrl+d
    C51单片机项目:红绿灯
    C51单片机项目:时钟
    java 笔记(1)在子类中,一定要访问父类的有参构造方法?
  • 原文地址:https://www.cnblogs.com/277223178dudu/p/14905265.html
Copyright © 2020-2023  润新知