c++实现大数运算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaokx3/article/details/79488723

刷上交大的题遇到大数运算的问题(权当记录)
题目描述如下:
Today, facing the rapid development of business, SJTU recognizes that more powerful calculator should be studied, developed and appeared in future market shortly. SJTU now invites you attending such amazing research and development work. In most business applications, the top three useful calculation operators are Addition (+), Subtraction (-) and Multiplication (×) between two given integers. Normally, you may think it is just a piece of cake. However, since some integers for calculation in business application may be very big, such as the GDP of the whole world, the calculator becomes harder to develop. For example, if we have two integers 20 000 000 000 000 000 and 4 000 000 000 000 000, the exact results of addition, subtraction and multiplication are: 20000000000000000 + 4000000000000000 = 24 000 000 000 000 000 20000000000000000 - 4000000000000000 = 16 000 000 000 000 000 20000000000000000 × 4000000000000000 = 80 000 000 000 000 000 000 000 000 000 000 Note: SJTU prefers the exact format of the results rather than the float format or scientific remark format. For instance, we need “24000000000000000” rather than 2.4×10^16. As a programmer in SJTU, your current task is to develop a program to obtain the exact results of the addition (a + b), subtraction (a - b) and multiplication (a × b) between two given integers a and b.
输入描述:
Each case consists of two separate lines where the first line gives the integer a and the second gives b (|a| <10^400 and |b| < 10^400).
输出描述:
For each case, output three separate lines showing the exact results of addition (a + b), subtraction (a - b) and multiplication (a × b) of that case, one result per lines.

c++实现:

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

#define Max 401

string Get_sum(int a[], int b[], int length) {
    string result = "";
    int s[Max] = {0};
    int to_high = 0, l = length, i;
    for (i = 0; i < l; i++) {
        s[i] = (a[i]+b[i]+to_high)%10;
        to_high = (a[i]+b[i]+to_high)/10;
    }
    if (to_high >0) s[l++] = 1;
    for (i = 0; i < l; i++) result.insert(0, to_string(s[i]));
    return result;
}

string Get_diff(int a[], int b[], int length) {
    string result = "";
    int s[Max] = {0};
    int need_high = 0, l = length, i;
    for (i = 0; i < l; i++) {
        if ((a[i]-need_high) < b[i]) {
            s[i] = a[i]+10-b[i]-need_high;
            need_high = 1;
        } else {
            s[i] = a[i]-b[i]-need_high;
            need_high = 0;
        }
    }
    for (i = 0; i < l; i++) result.insert(0, to_string(s[i]));
    while(result.length() >0) {
        if (result[0] == '0') result.erase(0,1);
        else break;
    }
    return result;
}

string Get_mul(int a[], int b[], int a_length, int b_length) {
    string result = "";
    int s[Max*2] = {0};
    for (int i = 0; i < a_length; i++) {
        for (int j = 0; j < b_length; j++) {
            s[i+j] += a[i]*b[j];
        }
    }
    int to_high = 0, total = a_length+b_length;
    for (int i = 0; i < total; i++) {
        int temp = s[i];
        s[i] = (temp+to_high)%10;
        to_high  = (temp+to_high)/10;
    }
    if (s[total-1] == 0) total -= 1;
    for (int i = 0; i < total; i++) result.insert(0, to_string(s[i]));
    return result;
}

int main() {
    string a, b;
    while (cin >> a >> b) {
        int s1[Max] = {0}, s2[Max] = {0};
        bool a_flag = false, b_flag = false;
        if (a[0] == '-') {
            a.erase(0,1);
            a_flag = true;
        }
        if (b[0] == '-') {
            b.erase(0,1);
            b_flag = true;
        }
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        unsigned int k;
        for (k = 0; k < a.length(); k++) s1[k] = a[k] - 48;
        for (k = 0; k < b.length(); k++) s2[k] = b[k] - 48;
        string result;
        int length = max(a.length(), b.length());
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        if ((!a_flag) && (!b_flag)) {
            cout << Get_sum(s1, s2, length) << endl;

            if (a.length() > b.length() || (a.length() == b.length() && a >= b)) // a >= b
                cout << Get_diff(s1, s2, length) << endl;
                // cout << "YES" <<endl;
            else cout << "-" << Get_diff(s2, s1, length) << endl;

            cout << Get_mul(s1, s2, a.length(), b.length()) << endl;
        } else if (a_flag && b_flag) {
            cout << "-" << Get_sum(s1, s2, length) << endl;

            if (b.length() > a.length() || (a.length() == b.length() && b >= a)) cout << Get_diff(s2, s1, length) << endl; // b >= a
            else cout << "-" << Get_diff(s1, s2, length) << endl;

            cout << Get_mul(s1, s2, a.length(), b.length()) << endl;
        } else {
            if ((!a_flag) && b_flag) {
                if (a.length() > b.length() || (a.length() == b.length() && a >= b)) // a >= b
                    cout << Get_diff(s1, s2, length) << endl;
                else cout << "-" << Get_diff(s2, s1, length) << endl;

                cout << Get_sum(s1, s2, length) << endl;
            } else {
                if (b.length() > a.length() || (a.length() == b.length() && b >= a)) cout << Get_diff(s2, s1, length) << endl; // b >= a
                else cout << "-" << Get_diff(s1, s2, length) << endl;

                cout << "-" << Get_sum(s1, s2, length) << endl;
            }
            cout << "-" << Get_mul(s1, s2, a.length(), b.length()) << endl;
        }
    }
    return 0;
}

关键点:
主要思想是利用字符串储存需要运算的大数,运算时按位运算并按位储存在int数组中,最后每位考虑进位的情况。即模拟人工手算过程。
大数运算乘法实现的关键在于要理解:一个数的第i 位和另一个数的第j 位相乘所得的数,一定是要累加到结果的第i+j 位上。这里i, j 都是从右往左,从0 开始数(反向储存在数组后则是按从左到右)。
即:result[i+j] += a[i]*b[j];

猜你喜欢

转载自blog.csdn.net/zhaokx3/article/details/79488723