大整数运算(加法、减法、乘法、除法、移位)

Table of Contents

BigNum 结构体定义

工具函数

getBigNum

printBigNum

format

运算

左移

加法

减法

乘法

除法

完整代码

C++

Java

 


 

BigNum 结构体定义

struct BigNum {
    int base; //进制
    int len; //数字长度,数字0我们认为是1位
    int d[MAX_SIZE];//数字的低位存在数组的低位,数字必须是正数。初始时数组全0

    BigNum() {
        len = 1
        base = 10;
        /*保证所有位均为0,避免影响运算*/
        for (int i = 0; i < MAX_SIZE; i++) {
            d[i] = 0;
        }
    }
};

 

工具函数

getBigNum

从字符串生成BigNum

 

BigNum getBigNum(string& str) {
    BigNum num;
    num.len = str.size();
    for (int i = 0; i < str.size(); i++) {
        num.d[str.size() - i - 1] = str[i] - '0';
    }
    return num;
}

printBigNum

打印BigNum

void printBigNum(BigNum num) {
    for (int i = num.len - 1; i >= 0; i--) {
        cout << char(num.d[i] + '0');
    }
    cout << endl;
}

 

format

格式化BigNum

void format(BigNum &num) {
    /*格式化每一位*/
    for (int i = 0; i < num.len; i++) {
        if (num.d[i] < 0) {
            num.d[i] += num.base;
            num.d[i + 1]--;
        }
        if (num.d[i] >= num.base) {
            int q = num.d[i] / num.base;
            num.d[i + 1] += q;
            num.d[i] -= q * num.base;
        }
    }
    /*判断是否为负数,用len=0标示其为负数*/
    if (num.d[num.len] < 0) {
        num.len = 0;
        return;
    }
    /*确定长度*/
    for (int i = num.len - 1; i >= 0; i--) {
        if (num.d[i] > 0) {
            num.len = i + 1;
            return;
        }
    }
    /*如果该数所有位数均为0,那么我们认为其长度为1,值为0*/
    num.len = 1;
}

 

 

运算

左移

BigNum operator<<(BigNum &num, int len) {
    BigNum ans;
    for (int i = num.len + len; i >= len; i--) {
        ans.d[i] = num.d[i - len];
    }
    for (int i = 0; i < len; i++) {
        ans.d[i] = 0;
    }
    ans.len = num.len + len;
    return ans;
}

 

 

加法

BigNum operator+(BigNum &num1, BigNum &num2) {
    BigNum ans = num1;
    for (int i = 0; i < num2.len; i++) {
        ans.d[i] += num2.d[i];//核心
    }
    ans.len = max(num1.len, num2.len) + 1;
    format(ans);
    return ans;
}

 

减法

BigNum operator-(BigNum &num1, BigNum &num2) {
    BigNum ans = num1;
    for (int i = 0; i < num2.len; i++) {
        ans.d[i] -= num2.d[i];//核心
    }
    ans.len = max(num1.len, num2.len);
    format(ans);
    return ans;
}

 

乘法

BigNum operator*(BigNum &num1, BigNum &num2) {
    BigNum ans;
    for (int i = 0; i < num1.len; i++) {
        for (int j = 0; j < num2.len; j++) {
            ans.d[i + j] += num1.d[i] * num2.d[j];//核心
        }
    }
    ans.len = num1.len + num2.len + 1;
    format(ans);
    return ans;
}

除法

BigNum operator/(BigNum &num1, BigNum &num2) {
    BigNum ans;
    ans.len = num1.len - num2.len + 1;
    for (int i = num1.len - num2.len; i >= 0; i--) {
        BigNum temp = num2 << i;//核心
        while ((num1 - temp).len != 0) {
            ans.d[i]++; //核心
            num1 = num1 - temp; //核心
        }
    }
    format(ans);
    return ans;
}

完整代码

C++

 

#include 

using namespace std;

#define MAX_SIZE 2000


struct BigNum {
    int base; //进制
    int len; //数字长度,数字0我们认为是1位
    int d[MAX_SIZE];//数字的低位存在数组的低位,数字必须是正数。初始时数组全0

    BigNum() {
        base = 10;
        len = 1;
        /*保证所有位均为0,避免影响运算*/
        for (int i = 0; i < MAX_SIZE; i++) {
            d[i] = 0;
        }
    }
};


BigNum getBigNum(string str) {
    BigNum num;
    num.len = str.size();
    for (int i = 0; i < str.size(); i++) {
        num.d[str.size() - i - 1] = str[i] - '0';
    }
    return num;
}


void printBigNum(BigNum num) {
    for (int i = num.len - 1; i >= 0; i--) {
        cout << char(num.d[i] + '0');
    }
    cout << endl;
}

void format(BigNum &num) {
    /*格式化每一位*/
    for (int i = 0; i < num.len; i++) {
        if (num.d[i] < 0) {
            num.d[i] += num.base;
            num.d[i + 1]--;
        }
        if (num.d[i] >= num.base) {
            int q = num.d[i] / num.base;
            num.d[i + 1] += q;
            num.d[i] -= q * num.base;
        }
    }
    /*判断是否为负数,如果为负数,令其长度为0*/
    if (num.d[num.len] < 0) {
        num.len = 0;
        return;
    }
    /*确定长度*/
    for (int i = num.len - 1; i >= 0; i--) {
        if (num.d[i] > 0) {
            num.len = i + 1;
            return;
        }
    }
    /*如果该数所有位数均为0,那么我们认为其长度为1,值为0*/
    num.len = 1;
}

BigNum operator<<(BigNum &num, int len) {
    BigNum ans;
    for (int i = num.len + len; i >= len; i--) {
        ans.d[i] = num.d[i - len];
    }
    for (int i = 0; i < len; i++) {
        ans.d[i] = 0;
    }
    ans.len = num.len + len;
    return ans;
}


BigNum operator+(BigNum &num1, BigNum &num2) {
    BigNum ans = num1;
    for (int i = 0; i < num2.len; i++) {
        ans.d[i] += num2.d[i];
    }
    ans.len = max(num1.len, num2.len) + 1;
    format(ans);
    return ans;
}


BigNum operator-(BigNum &num1, BigNum &num2) {
    BigNum ans = num1;
    for (int i = 0; i < num2.len; i++) {
        ans.d[i] -= num2.d[i];
    }
    ans.len = max(num1.len, num2.len);
    format(ans);
    return ans;
}

BigNum operator*(BigNum &num1, BigNum &num2) {
    BigNum ans;
    for (int i = 0; i < num1.len; i++) {
        for (int j = 0; j < num2.len; j++) {
            ans.d[i + j] += num1.d[i] * num2.d[j];
        }
    }
    ans.len = num1.len + num2.len + 1;
    format(ans);
    return ans;
}


BigNum operator/(BigNum &num1, BigNum &num2) {
    BigNum ans;
    ans.len = num1.len - num2.len + 1;
    for (int i = num1.len - num2.len; i >= 0; i--) {
        BigNum temp = num2 << i;

        while ((num1 - temp).len != 0) {
            ans.d[i]++;
            num1 = num1 - temp;
        }
    }
    format(ans);
    return ans;
}


int main() {
    string a, b;
    cin >> a >> b;
    BigNum n1 = getBigNum(a);
    BigNum n2 = getBigNum(b);
    printBigNum(n1 / n2);
}

Java

import java.util.Scanner;
import java.math.BigInteger;
public class Main{
    public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
        BigInteger a, b, c;
        a = sc.nextBigInteger();
        b = sc.nextBigInteger();
        c = a.divide(b);
        sc.close();
        System.out.println(c);
    }
}

 

你可能感兴趣的:(算法)