随手记——大整数运算模板(进化史)

大整数相加、相乘

2019年2月23日09:46:21

基本上没有空间浪费。关键是思路清晰,实现起来方便,字符串倒过来放到vector里(倒过来 方便进位运算),然后做完运算再逆序回来。

关于乘法运算,本来是每乘好一位,进位处理一次,其实可以最后统一进位。(统一进位的话最大范围:INT_MAX / 81,10^9位,完全够用了)。

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

void carry(vector<int>&a) {
    for (int i = 0; i < a.size(); i++) {
        if (i != a.size() - 1) a[i + 1] += a[i] / 10;
        else if (a[i] >= 10)a.push_back(a[i] / 10);
        a[i] %= 10;
    }
    while (a[a.size() - 1] == 0)a.pop_back();
    reverse(a.begin(), a.end());
}
void add(vector<int>&a, vector<int>b) {
    for (int i = 0; i < b.size(); i++) {
        a[i] += b[i];
    }
    carry(a);
}

void multi(vector<int>&a,vector<int>b) {
    //乘法运算,开两个数位数之和,确保不会超范围
    vector<int>t(a.size() + b.size());
    int k = 0;
    for (int i = 0; i < b.size(); i++) {
        for (int j = 0; j < a.size(); j++) {
            t[j + k] += (a[j] * b[i]);
        }
        k++;
    }
    carry(t);
    a = t;
}

void StringToArray(string s1, string s2, vector<int>&a, vector<int>&b) {
    if (s1.length() < s2.length())swap(s1, s2);
    for (int i = s1.length() - 1; i >= 0; i--) {
        a.push_back(s1[i] - '0');
    }
    for (int i = s2.length() - 1; i >= 0; i--) {
        b.push_back(s2[i] - '0');
    }
}

int main() {
    string s1 = "13234321324";
    string s2 = "232345444";
    long long l1 = 13234321324;
    long long l2 = 232345444;
    vector<int>a, b;
    cout << l1 * l2 << endl;
    StringToArray(s1, s2,a,b);
    multi(a, b);
    for (int i = 0; i < a.size(); i++) {
        cout << a[i];
    }
    cout << endl;

    return 0;
}
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int a[100], b[100];
int len1;

void carry() {
    int i = 0;
    for (int i = 0; i < len1; i++) {
        if (a[i] >= 10) {
            if (i == len1 - 1)len1++;
            a[i + 1] += a[i] / 10;
            a[i] %= 10;
        }
    }
}
void add() {
    for (int i = 0; i < len1; i++) {
        a[i] += b[i];
    }
    carry();
}
int main() {
    string s1="24354673235467", s2="25372472735767";
    long long l1= 24354673235467, l2= 25372472735767;
    //cin >> s1 >> s2;
    if (s2.length() > s1.length())swap(s1, s2);
    len1 = s1.length();
    for (int i = s1.length() - 1; i >= 0; i--) {
        a[s1.length() - i - 1] = s1[i] - '0';
    }
    for (int i = s2.length() - 1; i >= 0; i--) {
        b[s2.length() - i - 1] = s2[i] - '0';
    }
    add();
    for (int i = len1 - 1; i >= 0; i--) {
        cout << a[i];
    }
    cout << endl;
    cout << l1 + l2 << endl;
    return 0;
}

 

 大整数相减

2019年2月27日15:23:38,只能做正数相减运算

 https://code.mi.com/problem/list/view?id=3 

#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool flag = false;

void initialize(vector<int>&a, vector<int>&b) {
    flag = false;
    if (!a.empty())a.clear();
    if (!b.empty())b.clear();
}
void stringToArray(string s1, string s2, vector<int>&a, vector<int>&b) {
    for (int i = s1.length() - 1; i >= 0; i--) {
        a.push_back(s1[i] - '0');
    }
    for (int i = s2.length() - 1; i >= 0; i--) {
        b.push_back(s2[i] - '0');
    }
}

void carry(vector<int>&a) {
    //处理,11-12,这种情况
    while (a.size() > 1 && a[a.size() - 1] == 0)a.pop_back();
    for (int i = 0; i < a.size(); i++) {
        if (i != a.size() - 1 && a[i] < 0) {
            a[i] += 10;
            a[i + 1] -= 1;
        }
    }
}

void sub(vector<int>&a, vector<int>b) {
    if (a.size() < b.size()) {
        flag = true;
        swap(a, b);
    }
    for (int i = 0; i < b.size(); i++) {
        a[i] -= b[i];
    }
    carry(a);
}

int main() {
    vector<int>a, b;
    string s;
    while (cin >> s) {
        initialize(a, b);
        stringToArray(s.substr(0, s.find('-')), s.substr(s.find('-') + 1), a, b);
        sub(a, b);
        if (flag)a[a.size() - 1] = -a[a.size() - 1];
        for (int i = a.size() - 1; i >= 0; i--) {
            cout << a[i];
        }
        cout << endl;
    }
    return 0;
}
View Code

 

大数除小数

#include <iostream>
#include <time.h>
#include <string>
#include <vector>
using namespace std;

void divide(vector<int>&a, int b) {
    vector<int>v;
    int i, k, t = 0, s = 0;
    bool flag = true;
    for (i = 0, k = 0; i < a.size(); i++) {
        t = s * 10 + a[i];
        if (t / b > 0 || t == 0) {
            v.push_back(t / b);
            s = t % b;
            flag = false;
        }
        else {
            s = t;
            if (!flag)
                v.push_back(0);
        }
    }
    if (v.size() == 0)v.push_back(0);
    a = v;
}

void f(vector<int>&a,long long l) {
    while (l) {
        a.push_back(l % 10);
        l /= 10;
    }
    reverse(a.begin(), a.end());
}
int main() {
    srand(time(0));
    for (int i = 0; i < 100000; i++) {
        vector<int>a;
        long long l1, l2, ans = 0;
        l1 = rand() % 132456742353 + 1;
        l2 = rand() % 132456742353 + 1;
        //cin >> l1 >> l2;
        f(a, l1);
        divide(a, l2);
        for (int i = 0; i < a.size(); i++) {
            ans = ans * 10 + a[i];
        }
        if (ans != (l1 / l2)) {
            cout << "fuck" << endl;
        }

    }
    return 0;
}
View Code

 

posted @ 2019-02-12 16:17  czc1999  阅读(41)  评论(0编辑  收藏  举报