1. 程式人生 > >大數運算-模擬

大數運算-模擬

對於大數加法,減法和乘法都可以用模擬的方法來解決,對於除法(一直做減法),要使用加法和減法。

大數乘法

/*
Leetcode 43. Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string.
Note:
The numbers can be arbitrarily large and are non-negative.
Converting the input string to integer is NOT allowed.
You should NOT use internal library such as BigInteger.
解題思路:模擬手算。第i位乘以第j位得到的是(i+j)位的數
*/
#include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; class Solution { public: string multiply(string num1, string num2) { //先要反轉,把最低位放在0的位置 reverse(num1.begin(), num1.end()); reverse(num2.begin(), num2.end()); int
tmp = 0; string s(num1.length() + num2.length(), '0'); for (size_t i = 0; i < num1.length(); ++i) { for (size_t j = 0; j < num2.length(); ++j) { tmp = (num1[i] - '0') * (num2[j] - '0'); //tmp為i位*j位 //把進位加到i+j+1位上 s[i + j + 1
] = s[i + j + 1] - '0' + (s[i + j] - '0' + tmp) / 10 + '0'; //非進位的部分留在i+j位上 s[i + j] = (s[i + j] - '0' + tmp) % 10 + '0'; } } //處理完成後反轉 reverse(s.begin(), s.end()); //去掉前面的0 auto pos = s.find_first_not_of('0'); if (pos == string::npos) //為0的情況 return "0"; else return s.substr(pos); } }; void TEST() { Solution sol; string s1 = "123"; string s2 = "234"; cout << sol.multiply(s1, s2) << endl; } int main() { TEST(); return 0; }

大數除法(包含加法和減法)

/*
OpenJudge2737 大數除法
輸入兩個數,第一個被除數,第二個為除數,不超過100位
輸出:商的整數部分
*/

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>

using namespace std;

string sub(string s1, string s2)
{
    int flag = 0;
    if (s1.length() < s2.length() || ((s1.length() == s2.length()) && s1 < s2))
    {
        flag = 1;
        string tmp = s1;
        s1 = s2;
        s2 = s1;
    }

    int i, j;
    for (i = s1.length() - 1, j = s2.length() - 1; i >= 0; i--, j--)
    {
        s1[i] = char(s1[i] - (j >= 0 ? s2[j]-'0' : 0));
        if (s1[i] < '0')
        {
            --s1[i - 1];
            s1[i] += 10;
        }

    }

    for (i = 0; i < s1.length(); ++i)
    {
        if (s1[i] != '0') break;
    }
    if (i == s1.length()) i = s1.length() - 1;
    s1 = s1.substr(i);

    if (flag) s1 = "-" + s1;

    return s1;
}

string add(string s1, string s2)
{
    if (s1.length() < s2.length())
    {
        string tmp = s1;
        s1 = s2;
        s2 = tmp;
    }

    int i, j;
    for (i = s1.length() - 1, j = s2.length() - 1; i >= 0; --i,--j)
    {
        s1[i] = char(s1[i] + (j >= 0 ? s2[j] - '0' : 0));
        if (s1[i] - '0' >= 10)
        {
            s1[i] = (s1[i] - '0') % 10 + '0';
            if (i)
                s1[i - 1]++;
            else
                s1 = "1" + s1;
        }
    }

    return s1;
}

string div(string s1, string s2)
{
    string res = "0";
    if (s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2))
    {
        return "0";
    }

    int i;
    int subLen = s1.size() - s2.size();
    for (i = subLen; i >= 0; --i)
    {
        string s3(i, '0');
        string s4 = s2 + s3;
        //這裡做減法,直到s1比s4小
        do
        {
            string tmp = sub(s1, s4);
            if (tmp[0] == '-') break;   //不夠除
            else
            {
                s1 = tmp;
                res = add(res, ("1" + s3));//根據s3的位數來確定加的數
            }
        } while (1);
    }

    return res;
}

//順便把乘法寫了
string mul(string s1, string s2)
{
    reverse(s1.begin(), s1.end());
    reverse(s2.begin(), s2.end());

    int tmp = 0;
    string s(s1.size() + s2.size(), '0');
    for (int i = 0; i < s1.size(); ++i)
    {
        for (int j = 0; j < s2.size(); ++j)
        {
            tmp = (s1[i] - '0')*(s2[j] - '0');
            //進位
            s[i + j + 1] = s[i + j + 1] + (s[i + j] - '0' + tmp) / 10;
            //非進位
            s[i + j] = (s[i + j] - '0' + tmp) % 10 + '0';
        }
    }

    reverse(s.begin(), s.end());
    int pos = s.find_first_not_of('0');
    if (pos == -1)
        return "0";
    else
        return s.substr(pos);
}

int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    cout << div(s1, s2) << endl;

    return 0;
}