大数的处理

高精度问题之大数相乘

参考:http://blog.csdn.net/wu5151/article/details/47099971
AC代码如下

#include <iostream>  
#include <string>  
using namespace std;   

// 大数相乘   

string bigIntegerPlus(string res, string plusN) {  

    string ret;   
    if (res.length()< plusN.length()) {  

        string tmp = res;  
        res = plusN;  
        plusN = tmp;   
    }  

    int len1 = res.length(), len2 = plusN.length();  
    for (int i = len2-1; i>=0; --i ) {  

        string tmp(len1, '0'); // 存放相乘的中间结果   
        int goBit =0;  
        for (int j= len1-1; j >=0; --j) {  

            int mid = (res[j] -'0') * (plusN[i] -'0') + goBit;  
            tmp[j] = mid%10 + '0';  
            goBit = mid /10;  
        }  
        if (goBit != 0)   
            tmp.insert(0, string(1,goBit +'0'));  

        for (int m=0; m< len2 -1-i; ++m)  
            tmp.push_back('0'); // 补位    

        // 相乘后就相加  大数相加  
        if (i == len2-1)  
            ret = tmp;  
        else {  

            int goBit2 =0;   
            string s(tmp.length() - ret.length() ,'0');  
            ret = s + ret;  
            for (int m = tmp.length()-1; m>=0; --m) {  

                int mid = (tmp[m] -'0')+(ret[m] - '0')  + goBit2;  
                ret[m] = mid %10 +'0';  
                goBit2 = mid/ 10;     
            }  

            if (goBit2 != 0)   
                ret.insert(0, string(1,goBit +'0'));  
        }      
    }   

    // 去掉前导0  
    while (ret.length() >1 && ret[0] == '0')  
        ret.erase(0,1);  

    return ret;   
}  


int main(int argc, char** argv) {  

    string res, plusN;  
    while (cin>> res>> plusN) {  

        cout<< bigIntegerPlus(res, plusN)<< endl;  
    }  

    return 0;  
} 

总的思路比较简单, 就是模拟手算。 用较短(或相等)长度的数的每一位与较长数一一相乘。要注意的是,相乘所得结果需要补0的细节 。然后就是单纯的大数相加。
用c++的string来做 写起来挺顺手的。

面试题整理-大数求和

参考:http://www.cnblogs.com/findumars/p/4684361.html
题意很简单,就是求两个任意整数之和。
原题在: http://acm.hdu.edu.cn/showproblem.PHP?pid=1002
首先说一下正确的思路:

第一步:
输入的处理:
如果输入是00000123344需要处理为123344。
函数为:

[cpp] view plain copy
string &_del_zeros_before_dot(string &a)  
{  
    if (a.length() <= 0 || a[0] != '0') return a;  
    int i = 0;  
    while (i < a.length() && a[i] == '0') ++i;  
    a = a.substr(i, a.length() - i);  
    return a;  
}  

第二步:
求和,在求和的时候,因为两个正整数求和,最多增加的位数是1(也就是字符串的长度增加了1)。
再者需要把两个字符串都要处理完。在处理完两个字符串之后,一定要记得处理进位的情况。
这里简化了这些处理。看简单的代码。

[cpp] view plain copy
string &_string_add_string(const string &a, const string &b, string &res)  
{  
    int sum_value = 0, add_bit = 0;  
    const int alen = a.length(), blen = b.length();  
    res = "0" + (alen > blen ? a : b);  
    for (int i = alen-1, j = blen-1, k = res.length() - 1;   
         i >= 0 || j >= 0 || add_bit > 0;   
         --i, --j, --k){  
        sum_value = (i>=0 ? a[i]-48: 0) + (j>=0 ? b[j]-48: 0) + add_bit;  
        add_bit = sum_value / 10;   
        res[k] = sum_value%10 + '0';  
    }  
    if (res[0] == '0') res = res.substr(1, res.length() - 1);  
    return res;  
}  

由于结果第一位不能是0,所以最后需要把res的第一位做判断,是否删除。
第三步:
给出AC的代码

[cpp] view plain copy
#include <iostream>  
#include <string>  
using namespace std;  

string &_del_zeros_before_dot(string &a)  
{  
    if (a.length() <= 0 || a[0] != '0') return a;  
    int i = 0;  
    while (i < a.length() && a[i] == '0') ++i;  
    a = a.substr(i, a.length() - i);  
    return a;  
}  

string &_string_add_string(const string &a, const string &b, string &res)  
{  
    int sum_value = 0, add_bit = 0;  
    const int alen = a.length(), blen = b.length();  
    res = "0" + (alen > blen ? a : b);  
    for (int i = alen-1, j = blen-1, k = res.length() - 1;   
         i >= 0 || j >= 0 || add_bit > 0;   
         --i, --j, --k){  
        sum_value = (i>=0 ? a[i]-48: 0) + (j>=0 ? b[j]-48: 0) + add_bit;  
        add_bit = sum_value / 10;   
        res[k] = sum_value%10 + '0';  
    }  
    if (res[0] == '0') res = res.substr(1, res.length() - 1);  
    return res;  
}  

int main(void)  
{  
    string a, b, c;  
    int t;  
    scanf("%d", &t);  
    for (int i = 1; i < t + 1; ++i){  
        cin >> a >> b;   
        _del_zeros_before_dot(a);   
        _del_zeros_before_dot(b);  

        printf("Case %d:\n%s + %s = ", i, a.c_str(), b.c_str());  
        _string_add_string(a, b, c);  
        printf("%s\n", c.c_str());  

        if (i != t) printf("\n");  
    }  
    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值