大数加法和大数乘法的实现

问一个Facebook大数相乘的题
http://www.mitbbs.com/article_t1/JobHunting/32084397_0_1.html

两个大数相乘 char* multiply(char*,char*);
比如 char str1[] = "23456789009877666555544444"
char str2[] = "346587436598437594375943875943875"
最后求出他们的乘积

就是实现乘法的竖式实现。这是Leetcode上Multiplication那道题的程序,过了数据

    string multiply(string num1, string num2) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<int> res(num1.size () + num2.size (), 0);
        for (int i = 0; i < num1.size (); i++) {
            int carry = 0;
            for (int j = 0; j < num2.size (); j++) {
                int d1 = num1[num1.size () - 1 - i] - '0';
                int d2 = num2[num2.size () - 1 - j] - '0';
                carry = d1 * d2 + res[i + j] + carry;
                res[i + j] = carry % 10;
                carry = carry / 10;
            }
            res[i + num2.size ()] = carry;
        }
       
        int i = num1.size () + num2.size () - 1;
        while (i > 0 && res[i] == 0) i--;
        string result;
        while (i >= 0) result += char (res[i --] + '0');
       
        return result;
    }

这样空间和时间效率都不好。考虑到现在int一般是32位(4e9),每个int元素可以存多位十进制数。这样的话,单次int乘法的复杂度没有变化,但是总的乘法次数下降了,使用空间也相应下降了。

面世问这个比较变态把,没有任何技术含量,就是别错。string倒过来放,负号先拿掉
,返回pointer先malloc/new。还有什么注意事项么。

uva上有一道题要算满足一定条件的加()种数,recursion很快就写出来了,然后就要用
这个arbitrary precision integer arithmetic。写了个char*的结果TLE无数次。最后
有个大牛hint用vector<int>,然后每个int可以一次算9位数字,结果轻松过。

把两个操作数按一位、两位、三位或者四位十进制数(取决于int类型的大小)分割,存储成整弄数组,然后按照做乘法的步骤算一遍。空间复杂度O(m+n),时间复杂度O(mn),mn为两操作数的长度。

去年还是前年的google codejam qual有一道题是用这个的,neal_wu的code可以用来学习。

先写一个字符串相加的方法,然后用小学学过的办法,一位一位来。。
这题是POJ 1001的一个子算法。

=================

接下来是大数加法,这个就简单了.

void AddTwoLargeNumbers(const string str1, const string str2, string &str3)
{
  /*assume str1 and str2 have been validated.*/
  int len1 = str1.length();
  int len2 = str2.length();
  int len3 = 1 + ((len1>len2) ? len1 : len2);
  str3.resize(len3);

  int a = 0;
  int pos = 0;
  int d1, d2, d3;
  while (pos < len3)
  {
    str3[len3-pos-1] = '0';

    d1 = (pos < len1) ? str1.at(len1-pos-1)-0x30 : 0;
    d2 = (pos < len2) ? str2.at(len2-pos-1)-0x30 : 0;
    d3 = d1 + d2 + a;

    a = d3/10;

    d3=d3%10;

    str3[len3-pos-1] = d3 + 0x30;
    pos++;
  }
  if (str3[0] == '0')
  {
      str3.erase(0, 1);
  }
 
  return;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值