• A+B and A*B problem 大数相加 相乘 模拟


    A+B and A*B problem 大数相加 相乘 模拟

    题意

    给你两个数a和b,这两个数很大,然后输出这两个数相加的和,相乘的积。

    解题思路

    模拟,但是还是搜了搜代码实现,发现这个大佬写的是真的简洁高效。

    下面第一个代码转自博客(修改了一些) 》》》https://blog.csdn.net/hacker00011000/article/details/51298294

    第二个代码是CZH同学的代码,代码更是简单易懂!

    别的一些思路

    大数相加相乘 https://blog.csdn.net/weixin_41162823/article/details/80044079

    高精度快速幂 https://www.luogu.org/problemnew/solution/P1045

    代码实现

    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    using namespace std;
    
    //C++大数相加
    string BigNumAdd(const string& strNum1, const string& strNum2)
    {
        string strSum;
        int len1 = strNum1.size()-1;
        int len2 = strNum2.size()-1;
        int bit = 0;                //保存进位
    
        //从结尾开始每位相加 
        while (len1>=0 && len2>=0)
        {
            //求每位的和(要把进位也加上) 
            int tmpSum = strNum1[len1]-'0' + strNum2[len2]-'0' + bit;
            //保存进结果 
            strSum += tmpSum % 10 + '0';
            //求进位 
            bit = tmpSum / 10;
            --len1;
            --len2; 
        }
    
        //两个整数长度不相等(肯定有一个已经加完了,不需要再额外加if来判断,因为while就可以判断)
        while (len1 >= 0)
        {
            //和上个while循环一样
            int tmpSum = strNum1[len1]-'0' + bit;
            strSum += tmpSum % 10 + '0';
            bit = tmpSum / 10;
            --len1; 
        }
        while (len2 >= 0) 
        {
            //和上个while循环一样
            int tmpSum = strNum2[len2]-'0' + bit;
            strSum += tmpSum % 10 + '0';
            bit = tmpSum / 10;
            --len2; 
        }
    
        //最高位有进位
        if (bit != 0)
            strSum += bit + '0'; 
    
        //反转
        reverse(strSum.begin(), strSum.end()); 
    
        return strSum;
    }
    
    //C++大数相乘
    string BigNumMultiply(const string& strNum1, const string& strNum2)
    {
        string strMultiply;
        //两数相乘最大有m+n位
        int bit = 0;
        int len1 = strNum1.size()-1;
        int len2 = strNum2.size()-1;
    
        //计算每一位 
        for (int i=0; i<len1+len2+2; ++i)
        {
            //计算结果的第i位(权值肯定为i,第1位也就是个位权值为0(pow(10, 0))) 
            //等于乘数的第(i~0)位分别与被乘数的第(0~i)位相乘,因为这样每位相乘之后权值仍为i 
            //然后相加再加上前一位的进位,就是结果的第i位
            //然后%10得出第i位,/10得到进位
            int tmp = 0;
            for (int j=i; j>=0; --j)
            {
                //如果下标超出字符串的范围   j为num1的下标, i-j为num2的下标,然后两数相乘 
                if (j>len1 || (i-j)>len2)
                    continue;
    
                //还要注意字符串数字的最高位在字符串的最低位所以得用len减去 
                tmp += (strNum1[len1-j]-'0') * (strNum2[len2-(i-j)]-'0');
            }
            //加上进位
            tmp += bit;
            //为了防止最后一位是0,但是却加上了
            if (tmp == 0 && i == len1+len2+1) 
                break;
            //求余得到结果的第i位
            strMultiply += tmp % 10 + '0';
            //计算新的进位
            bit = tmp / 10; 
        }
    
        //判断结果的最后一个字符如果是0的话说明可以删去
        //if (strMultiply[strMultiply.size()-1] == '0')
        //  strMultiply[strMultiply.size()-1] = '';
    
        //反转
        reverse(strMultiply.begin(), strMultiply.end()); 
    
        return strMultiply;
    }
    
    int main()
    {
        string str1;
        string str2;
        cin >> str1 >> str2;
    
        //相加和相乘
        cout << BigNumAdd(str1, str2) << endl;
        cout << BigNumMultiply(str1, str2) << endl; 
        return 0;
    }
    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 10010;
    int a[maxn],b[maxn];
    int ans[maxn];
    int ans2[maxn];
    
    int main()
    {
    	string s1,s2;
    	cin>>s1>>s2;
    	int len1 = s1.length();
    	int len2 = s2.length();
    	int lenans = 0, lenans2 = 0;
    	int n = 0;
    	
    	for(int i=0;i<len1;i++)
    		a[i] = s1[i]-'0';
    	reverse(a, a+len1);
    	
    	for(int i=0;i<len2;i++)
    	{
    		b[i] = s2[i]-'0';
    		n = n*10 + s2[i]-'0';
    	}
    	reverse(b, b+len2);
    	
    	for(int i=0,up=0;i<maxn;i++)
    	{
    		ans[i] = a[i]+b[i]+up;
    		up = ans[i]/10;
    		ans[i] %= 10;
    	}
    	
    	for(int i=maxn-1;i!=-1;i--)
    	{
    		if(ans[i])
    		{
    			lenans = i;
    			break;
    		}
    	}
    	
    	for(int i=lenans;i!=-1;i--)
    		cout<<ans[i];
    	cout<<endl;
    	
    	for(int i=0;i<maxn;i++)
    	{
    		ans2[i] = a[i]*n+ans2[i];
    		ans2[i+1] = ans2[i]/10;
    		ans2[i] %= 10;
    	}
    	for(int i=maxn-1;i!=-1;i--)
    	{
    		if(ans2[i])
    		{
    			lenans2 = i;
    			break;
    		}
    	}
    	for(int i=lenans2;i!=-1;i--)
    		cout<<ans2[i];
    	cout<<endl;
    	
    	return 0;
    }
    
    #include<cstdio>
    #include<iostream> 
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=100;
    char a[maxn], b[maxn];
    int len, len1, len2;
    int anum[maxn], bnum[maxn], sum[maxn];
    int main()
    {
    	cin>>a>>b;
    	len1=strlen(a);
    	len2=strlen(b);
    	len=max(len1, len2);
    	for(int i=len1-1, j=0; i>=0; i--, j++)
    		anum[j]=a[i]-'0';
    	for(int i=len2-1, j=0; i>=0; i--, j++)
    		bnum[j]=b[i]-'0';
    	for(int i=0; i<=len; i++)
    	{
    		sum[i]+=anum[i]+bnum[i];
    		if(sum[i]>9)
    		{
    			sum[i+1]+=sum[i]/10;
    			sum[i]%=10;
    		}
    	}
    	int begin=0;
    	for(int i=len; i>=0; i--)
    	{
    		if(sum[i]!=0)
    		{
    			begin=i;
    			break;
    		}
    	}
    	for(int i=begin; i>=0; i--)
    		cout<<sum[i];
    	cout<<endl;
    	
    	memset(sum, 0, sizeof(sum));
    	for(int i=0; i<len1; i++)
    	{
    		for(int j=0; j<len2; j++)
    			sum[i+j]+=anum[i]*bnum[j];
    	}
    	for(int i=0; i<=len1+len2; i++)
    	{
    		if(sum[i]>9)
    		{
    			sum[i+1]+=sum[i]/10;
    			sum[i]%=10;
    		}
    	}
    	begin=0;
    	for(int i=len1+len2; i>=0; i--)
    		if(sum[i]!=0)
    		{
    			begin=i;
    			break;
    		}
    	for(int i=begin; i>=0; i--)
    		cout<<sum[i];
    	cout<<endl;
    	
    	return 0;
     } 
    
    欢迎评论交流!
  • 相关阅读:
    <form:select>的使用
    存储过程-删除、新建索引
    java 反射常用总结
    java判断是否是数字
    jquery遍历数组添加行删除行
    oracle常用sql
    cxf (zhuan)
    linux 常用命令--个人小结一
    java发送邮件
    socket和webservice特点
  • 原文地址:https://www.cnblogs.com/alking1001/p/11574812.html
Copyright © 2020-2023  润新知