Java大数运算

Java大数运算

问题描述:计算 2^1000 的值

1、运算思路

1、首先计算结果肯定会超出系统提供的数据类型,不能采用常规数据类型处理。
2、采用字符串或者字符数组、集合表示
3、本体采用ArrayList集合来存储,在不确定数组长度时可能会产生一部分内存浪费
4、采用笔算常用的计算方式将大数分割成每一位进行单独运算,并处理好进位。
5、尽可能的缩小循环体执行次数

2、编码步骤

1、转化为4^5000次方计算

1、代码内容
//大循环需要执行5000次,整体执行7528246次
//同样将乘数换成8最后在乘一个2,也可以得到,而且更高效。
import java.util.ArrayList;
import java.util.List;

public class main01 {
    public static void main(String[] args) {
        long count = 0;
        long startTime = System.currentTimeMillis();

        String num1 = "2";
        char[] a = num1.toCharArray();
        List<Integer> list_source = new ArrayList<Integer>();
        List<Integer> list_new = new ArrayList<Integer>();
        for (int i = 0; i < a.length; i++) {
            list_source.add(Integer.parseInt(a[i] + ""));
        }

        for (int j = 0; j < 5000; j++) {

            int length = list_source.size();
            int num = 0;
            int temp = 0;

            for (int i = 0; i < length; i++) {
                count++; // 循环次数计算器
                temp = list_source.get(length - 1 - i); // 将集合中的最后一个元素取出
                temp = temp * 4; // 用该元素进行计算
                num += temp; // 计算出的结果要加上上一个的进位
                list_new.add(0, num % 10); // 将个位加入新的集合
                num = num / 10; // 获取进位值
                // System.out.println(num);
            }
            if (num != 0) { // 在循环退出后,处理最后的进位
                list_new.add(0, num);
            }
            list_source.clear();
            list_source.addAll(list_new);
            list_new.clear();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("时间:" + (endTime - startTime));
        System.out.println("循环次数:" + count);
        for (Integer i : list_source) {
            System.out.print(i);
        }

    }
}
2、输出结果显示
时间:1438
循环次数:7528246
39901262337615167697674843253671701676469936637723849097040178997058877660443893263839923368072389195798662258846418248543112982698827562235187571864192647915711460093587589053530493102532119791041100173836386623085017216921236209371018149732179249776180979789676018507883266515701243136618947805113824776130450193287748882093519743253970906445737076323388631551259281525673761521464457070183282952367912762917938927798821681921072535642129242854666788073051131299061206285360469938800671868633302918595546559331551212345164062815988396359214756491367524560074605770974503801668929162909301115859202829667843231469176278514190759538238555601653915471348888246124037515672651005456647578541420747605732786062856266482803248391343381148122839308684649277602497712294610414863984519223592500261985720483416681615211864640322536984576992511682625688123073477902974228512630222179491028406627640405863281915192929512020811691683132144089925734033030123841262008372844551817341801149212835713903822912110136502500812015039684523796118474236108889576145812790485096678443965414808946324753521693226067557412079606826394266987309245401126339874911016483561945621966582628807143755049537019714553875852866443198799753773321616737675676055286565550344547315145489568224588779467621723214846506583949626240395208356563931394951796329062516868271919725568260256370812566953298177381042095161765231647923971540244814088661166151738078639209206809946313166417344211826601807505646831079490788795430514910581020424621894643221506949651481550547972696596996681513875911293277243749138998558033144207402728866271634428623582796445967691694668880541928365702010145855496729101157269002201705975624778947857399081668692317614087918237971630291558354287239397456262918967566404162949964343716022778142456501811653634872441154951842835307431375451229809165809984922057260163071166616260203975351712468687077910818351246801689775052325287137297667038927440754586480188912493846508700801356054547675510752813453797272482074982821933437114101518196200493579760356543851906762564843908056605518816897910029353336779395993772483272626752787806746911602815273483755422110768451478998220372936439393163302970260988444739895429526138310936435365752400725554515447562730663222393622561585338963774402597287321537103279721069204595743115035894770492738893846175788531896434016102240644730992576338071478242736676787183512837467701021940543227830879181983196309308834672623313872062244499875939998453563464716046223725289150598271516350016399678472569230499762177920464488724347543236172714030936968117244659585707751246973112881073925244037927142057624723135025086676606540058195337301137114315011033455037798388259422675380299832362630343088015457301146379114901840660370609694227636630814648106638076924168072843527407823101279578001485707344392561806955949066640936737591737160475904437258240161485639102635896315248896597036923019409776054549443149376263189500819464230160996380911606833653899574282632126421372783023363548609585193418752

2、转化为 1024^1000次方计算

//主循环体执行1000,但将1024分割后会产生四组值需要对他们进行加和,还要保持进位和对齐,因此,循环次数会大部分浪费在元素加和计算上。
public class main03 {
    static long count =0;
    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();
        String num1 = "2";
        int Multiplier = 1024;

        char[] a = num1.toCharArray();
        List<Integer> list_source = new ArrayList<Integer>(); // 源数据集合

        List<Integer> list01 = new ArrayList<Integer>(); // 乘数集合
        List<Integer> list02 = new ArrayList<Integer>(); // 乘数集合
        List<Integer> list03 = new ArrayList<Integer>(); // 乘数集合
        List<Integer> list04 = new ArrayList<Integer>(); // 乘数集合

        List<Integer> list_new = new ArrayList<Integer>(); // 新数据集合
        for (int i = 0; i < a.length; i++) {
            list_source.add(Integer.parseInt(a[i] + ""));
        }
        //循环求乘方
        for (int j = 0; j < 1000; j++) {

            list01 = test(list_source, Multiplier % 10); // 不变
            list02 = test(list_source, Multiplier / 10 % 10); // 最后填一个0
            list03 = test(list_source, Multiplier / 100 % 10); // 最后天两个0
            list04 = test(list_source, Multiplier / 1000); // 最后天三个0

            // 对三个集合进行求和
            list02.add(list02.size(), 0);
            list03.add(list03.size(), 0);
            list03.add(list03.size(), 0);
            list04.add(list04.size(), 0);
            list04.add(list04.size(), 0);
            list04.add(list04.size(), 0);

            // 补齐
            int len = list04.size() - list03.size();
            for (int i = 0; i < len; i++) {
                list03.add(0, 0);
                count ++; //循环次数计数器
            }
            len = list04.size() - list02.size();
            for (int i = 0; i < len; i++) {
                list02.add(0, 0);
                count ++; //循环次数计数器
            }
            len = list04.size() - list01.size();
            for (int i = 0; i < len; i++) {
                list01.add(0, 0);
                count ++; //循环次数计数器
            }
            // 集合求和
            int length = list04.size();
            int num = 0;
            for (int i = 0; i < length; i++) {
                count ++; //循环次数计数器
                num = list01.get(length - 1 - i) + list02.get(length - 1 - i)
                        + list03.get(length - 1 - i)
                        + list04.get(length - 1 - i) + num;
                list_new.add(0, num % 10);
                num = num / 10;
            }
            if (num != 0) {
                list_new.add(0, num);
            }
            // 循环乘方的话,需要对换。
            list_source.clear();
            list_source.addAll(list_new);
            list_new.clear();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("时间:" + (endTime - startTime));
        System.out.println("循环次数:"+count);
        for(Integer i:list_source){
            System.out.print(i);
        }

    }

    private static List<Integer> test(List<Integer> list_source, int Multiplier) {
        List<Integer> list_new = new ArrayList<Integer>();
        int length = list_source.size();
        int num = 0;
        int temp = 0;

        for (int i = 0; i < length; i++) {
            count ++; //循环次数计数器
            temp = list_source.get(length - 1 - i); // 将集合中的最后一个元素取出
            temp = temp * Multiplier; // 用该元素进行计算
            num += temp; // 计算出的结果要加上上一个的进位
            list_new.add(0, num % 10); // 将个位加入新的集合
            num = num / 10; // 获取进位值

        }
        if (num != 0) { // 在循环退出后,处理最后的进位
            list_new.add(0, num);
        }
        return list_new;

    }

}
2、结果显示
时间:1642
循环次数:7530338
39901262337615167697674843253671701676469936637723849097040178997058877660443893263839923368072389195798662258846418248543112982698827562235187571864192647915711460093587589053530493102532119791041100173836386623085017216921236209371018149732179249776180979789676018507883266515701243136618947805113824776130450193287748882093519743253970906445737076323388631551259281525673761521464457070183282952367912762917938927798821681921072535642129242854666788073051131299061206285360469938800671868633302918595546559331551212345164062815988396359214756491367524560074605770974503801668929162909301115859202829667843231469176278514190759538238555601653915471348888246124037515672651005456647578541420747605732786062856266482803248391343381148122839308684649277602497712294610414863984519223592500261985720483416681615211864640322536984576992511682625688123073477902974228512630222179491028406627640405863281915192929512020811691683132144089925734033030123841262008372844551817341801149212835713903822912110136502500812015039684523796118474236108889576145812790485096678443965414808946324753521693226067557412079606826394266987309245401126339874911016483561945621966582628807143755049537019714553875852866443198799753773321616737675676055286565550344547315145489568224588779467621723214846506583949626240395208356563931394951796329062516868271919725568260256370812566953298177381042095161765231647923971540244814088661166151738078639209206809946313166417344211826601807505646831079490788795430514910581020424621894643221506949651481550547972696596996681513875911293277243749138998558033144207402728866271634428623582796445967691694668880541928365702010145855496729101157269002201705975624778947857399081668692317614087918237971630291558354287239397456262918967566404162949964343716022778142456501811653634872441154951842835307431375451229809165809984922057260163071166616260203975351712468687077910818351246801689775052325287137297667038927440754586480188912493846508700801356054547675510752813453797272482074982821933437114101518196200493579760356543851906762564843908056605518816897910029353336779395993772483272626752787806746911602815273483755422110768451478998220372936439393163302970260988444739895429526138310936435365752400725554515447562730663222393622561585338963774402597287321537103279721069204595743115035894770492738893846175788531896434016102240644730992576338071478242736676787183512837467701021940543227830879181983196309308834672623313872062244499875939998453563464716046223725289150598271516350016399678472569230499762177920464488724347543236172714030936968117244659585707751246973112881073925244037927142057624723135025086676606540058195337301137114315011033455037798388259422675380299832362630343088015457301146379114901840660370609694227636630814648106638076924168072843527407823101279578001485707344392561806955949066640936737591737160475904437258240161485639102635896315248896597036923019409776054549443149376263189500819464230160996380911606833653899574282632126421372783023363548609585193418752

3、继续转换获取最高效的结果

……(待续)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值