长整数类BigInt

Kevin_K edited 5 年,11 月前

渣渣我曾经励志与高精度拼了,我今天就来证明一下本渣已经迈出了关键的一小步~~(其实是因为XXXX的Java作业才写的)~~。为了方便打包使用,使用Java编写。~~(我实在是编不下去了233)~~
祖传源代码:

package BigInt;
import java.util.*;
public final class BigInt{
    //变量
    private boolean neg=false;
    private ArrayList<Integer> num=new ArrayList<Integer>();
    //构造
    public BigInt(){
        num.add(0);
    }
    public BigInt(String s){
        neg=reading(s,num);
        if (num.size()==1&&num.get(0)==0){
            neg=false;
        }
    }
    //性质
    public int length(){
        return num.size();
    }
    public boolean negative(){
        return neg;
    }
    //辅助
    private void leadingZeroSuppress(ArrayList<Integer> x){
        for (int i=x.size()-1;i>0;i--){
            if (x.get(i)!=0){
                return;
            }
            x.remove(i);
        }
    }
    private void leadingZeroAdd(ArrayList<Integer> x,int y){
        for (int i=0;i<y;i++){
            x.add(0);
        }
    }
    private boolean reading(String x,ArrayList<Integer> y){
        boolean z=false;
        y.clear();
        int end=0;
        if (x.charAt(0)=='-'){
            end=1;
            z=true;
        }
        for (int i=x.length()-1;i>=end;i--){
            y.add((int)x.charAt(i)-(int)'0');
        }
        leadingZeroSuppress(y);
        return z;
    }
    private ArrayList<Integer> copyList(ArrayList<Integer> x){
        ArrayList<Integer> y=new ArrayList<Integer>();
        for (int i=0;i<x.size();i++){
            y.add(x.get(i));
        }
        return y;
    }
    private void multiplyTen(ArrayList<Integer> x,int y){
        for (int i=0;i<y;i++){
            x.add(0,0);
        }
    }
    private ArrayList<Integer> multiplyBasic(ArrayList<Integer> x,int y){
        int temp=0,p=0;
        ArrayList<Integer> res=new ArrayList<Integer>();
        leadingZeroAdd(x,1);
        leadingZeroAdd(res,x.size());
        for (int i=0;i<x.size();i++){
            p=x.get(i)*y+temp;
            res.set(i,p%10);
            temp=(p-p%10)/10;
        }
        leadingZeroSuppress(x);
        leadingZeroSuppress(res);
        return res;
    }
    private BigInt divideBasicAbs(BigInt x){
        ArrayList<Integer> tnum=new ArrayList<Integer>();
        ArrayList<Integer> res=new ArrayList<Integer>();
        boolean tneg=reading(x.toString(),tnum);
        ArrayList<BigInt> group=new ArrayList<BigInt>();
        BigInt ten=new BigInt("10");
        for (int i=1;i<=10;i++){
            BigInt temp=new BigInt(String.valueOf(i));
            temp=temp.multiply(x);
            BigInt tem=new BigInt(temp.toStringAbs());
            group.add(tem);
        }
        BigInt abs=new BigInt(toStringAbs());
        for (int i=abs.length()-1;i>=0;i--){
            BigInt comp=new BigInt(abs.toStringHigherPartAbs(i));
            for (int j=0;j<10;j++){
                if (group.get(j).compareAbs(comp)>0){
                    res.add(0,j);
                    if (j==0){
                        break;
                    }
                    comp=group.get(j-1);
                    for (int k=0;k<i;k++){
                        comp=comp.multiply(ten);
                    }
                    abs=abs.subtract(comp);
                    break;
                }
            }
        }
        leadingZeroSuppress(res);
        BigInt ans=new BigInt(toStringAbs(res));
        return ans;
    }
    //输出
    private String toStringAbs(ArrayList<Integer> x){
        String res="";
        for (int i=x.size()-1;i>=0;i--){
            res+=String.valueOf(x.get(i));
        }
        return res;
    }
    private String toString(ArrayList<Integer> x,boolean y){
        if (y==true){
            return "-"+toStringAbs(x);
        }
        return toStringAbs(x);
    }
    private String toStringOpposite(ArrayList<Integer> x,boolean y){
        if (y==true){
            return toString(x,false);
        }
        return toString(x,true);
    }
    private String toStringHigherPartAbs(ArrayList<Integer> x,int y){
        ArrayList<Integer> temp=new ArrayList<Integer>();
        leadingZeroSuppress(x);
        if (y<0){
            y=0;
        }
        if (y>=x.size()){
            temp.add(0);
        }
        for (int i=y;i<x.size();i++){
            temp.add(x.get(i));
        }
        return toStringAbs(temp);
    }
    public String toStringAbs(){
        return toStringAbs(num);
    }
    public String toString(){
        return toString(num,neg);
    }
    public String toStringOpposite(){
        return toStringOpposite(num,neg);
    }
    public String toStringHigherPartAbs(int x){
        return toStringHigherPartAbs(num,x);
    }
    //比较
    public boolean equals(BigInt x){
        if (toString().equals(x.toString())){
            return true;
        }
        return false;
    }
    public int compareAbs(BigInt x){
        boolean cneg=false;
        ArrayList<Integer> cnum=new ArrayList<Integer>();
        cneg=reading(x.toStringAbs(),cnum);
        int l=Math.max(num.size(),cnum.size());
        leadingZeroAdd(num,l-num.size());
        leadingZeroAdd(cnum,l-cnum.size());
        int jud=toStringAbs(num).compareTo(toStringAbs(cnum));
        leadingZeroSuppress(num);
        if (jud>0){
            return 1;
        }
        if (jud<0){
            return -1;
        }
        return 0;
    }
    public int compare(BigInt x){
        if (neg!=x.negative()){
            if (neg){
                return -1;
            }
            return 1;
        }
        if (neg){
            return -compareAbs(x);
        }
        return compareAbs(x);
    }
    //运算
    public BigInt add(BigInt x){
        ArrayList<Integer> tnum=new ArrayList<Integer>();
        boolean tneg=reading(x.toString(),tnum);
        int temp=0;
        if (neg==tneg){
            temp=0;
            int l=Math.max(tnum.size(),num.size())+1;
            leadingZeroAdd(num,l-num.size());
            leadingZeroAdd(tnum,l-tnum.size());
            for (int i=0;i<l;i++){
                int p=tnum.get(i)+num.get(i)+temp;
                tnum.set(i,p%10);
                temp=(p-tnum.get(i))/10;
            }
            leadingZeroSuppress(num);
            leadingZeroSuppress(tnum);
            BigInt res=new BigInt(toString(tnum,tneg));
            tnum.clear();
            tneg=false;
            return res;
        }
        if (compareAbs(x)==0){
            BigInt res=new BigInt();
            tnum.clear();
            tneg=false;
            return res;
        }
        boolean bneg,sneg;
        ArrayList<Integer> bnum=new ArrayList<Integer>();
        ArrayList<Integer> snum=new ArrayList<Integer>();
        if (compareAbs(x)==1){
            bnum=copyList(num);
            snum=copyList(tnum);
            bneg=neg;
            sneg=tneg;
        }
        else{
            snum=copyList(num);
            bnum=copyList(tnum);
            bneg=tneg;
            sneg=neg;
        }
        temp=0;
        leadingZeroAdd(snum,bnum.size()-snum.size());
        for (int i=0;i<bnum.size();i++){
            int bit=bnum.get(i)-snum.get(i)-temp;
            if (bit<0){
                temp=1;
                bit+=10;
            }
            else{
                temp=0;
            }
            bnum.set(i,bit);
        }
        temp=0;
        tnum.clear();
        snum.clear();
        tneg=false;
        sneg=false;
        leadingZeroSuppress(bnum);
        if (bneg==true){
            BigInt res=new BigInt("-"+toStringAbs(bnum));
            bneg=false;
            bnum.clear();
            return res;
        }
        BigInt res=new BigInt(toStringAbs(bnum));
        bneg=false;
        bnum.clear();
        return res;
    }
    public BigInt subtract(BigInt x){
        BigInt res=new BigInt(x.toStringOpposite());
        return add(res);
    }
    public BigInt multiply(BigInt x){
        ArrayList<Integer> tnum=new ArrayList<Integer>();
        boolean tneg=reading(x.toString(),tnum);
        if (neg==tneg){
            tneg=false;
        }
        else{
            tneg=true;
        }
        BigInt res=new BigInt();
        for(int i=0;i<num.size();i++){
            ArrayList<Integer> temp=new ArrayList<Integer>();
            temp=multiplyBasic(tnum,num.get(i));
            multiplyTen(temp,i);
            BigInt part=new BigInt(toStringAbs(temp));
            res=res.add(part);
        }
        if (tneg){
            BigInt resReal=new BigInt(res.toStringOpposite());
            return resReal;
        }
        return res;
    }
    public BigInt divide(BigInt x){
        if (x.negative()==neg){
            return divideBasicAbs(x);
        }
        BigInt res=new BigInt(divideBasicAbs(x).toStringOpposite());
        return res;
    }
    public BigInt mod(BigInt x){
        BigInt y=new BigInt(toString());
        return y.subtract(x.multiply(y.divide(x)));
    }
    public BigInt absFact(){
        BigInt i=new BigInt(toStringAbs());
        BigInt unit=new BigInt("1");
        BigInt res=new BigInt("1");
        while (!i.equals(unit)){
            res=res.multiply(i);
            i=i.subtract(unit);
        }
        return res;
    }
    public BigInt intPowAbs(int x){
        if (x<0){
            x=-x;
        }
        BigInt res=new BigInt("1");
        BigInt unit=new BigInt(toString());
        for (int i=0;i<x;i++){
            res=res.multiply(unit);
        }
        return res;
    }
}

完成及初步检查完成时间:2018年4月21日15:56:48。
现在看起来那时候还是太年轻了,写的冗长又低效,但是即使现在让我重写,我大概也只能写的不怎么冗长,所以就没有改动。~~(其实是我懒啦!几百行的代码改起来超级累的呢!)~~
包含的API(懒得写,自己过去看吧,虽然还实现了一些杂七杂八的API~~(其实你可以当彩蛋看QwQ)~~,但核心就这些了)。
与Java自带的长整数类BigInteger的性能差异大概长这样:
404!
如你所见,粗略估计比BigInteger快了十倍不止,恐怖如斯!
(其实我也很绝望的啊T_T)


注:
1.求大佬不要笑话和嘲讽,本渣的小心脏会受不了的。
2.其实本文还有个起誓的作用:我Kevin_K就是WA、RE、CE,也不会再用Java刷OJ了!(Java,与我ArrayList,降我模力,使我无故TLE,非英雄也!)
3.祝God West明天码运昌隆,AK全场!

Comments

Kevin_K

我怕不是用了假的Markdown哦......算了不管了。

10175102211

轩爷牛逼!