java黑皮书22.8----(不大于10000000000的所有素数)

该博客介绍了一个使用BigInteger处理大整数的Java程序,旨在生成不超过100亿的素数并将其存储到二进制文件中。程序实现了断点续传功能,允许在中断后继续之前的计算。主要难点在于二进制文件的读写和素数检测。程序通过读取临时记录文件来恢复上次的计算状态,并将每10000个素数写入文件,同时更新进度记录。
摘要由CSDN通过智能技术生成

问题描述

提示:一般我是用不到UNIX机器的,所以我这里的批处理其实是伪批处理,可以段断点续传:

将不大于10000000000的素数输入到一个名为PrimeNumber.dat的二进制文件中


难点分析:

提示:这里难点是断点续传,但是其实就是文本再次读写而已,我认为最难的是没学过二进制文件的处理,这里我们秉持实用主义,会用就好,其中的原理其实我也不太清楚,有时间可以学一下:

是首先,我准备用BigInteger来做,这个主要是为了应对之后教材与设备的更新,其实Long已经完全满足题意了,个人感觉用Long估计还快很多,long最大是10的19次方多,已经完全满足题目要求了,关于long的代码,各位稍微改改就好,这里就不用写了,毕竟改改我这里的数据就好了。

问题求解一:求素数:

        while (number.compareTo(new BigInteger("10000000000")) <= 0) {
            boolean isPrime = true;

            if (squareRoot.multiply(squareRoot).compareTo(number) < 0)
                squareRoot = squareRoot.add(new BigInteger("1"));


            for (int i = 0; i < list.size()
                    && list.get(i).compareTo(squareRoot) <= 0; i++) {
                if (number.remainder(list.get(i)).equals(new BigInteger("0"))) {
                    isPrime = false;
                    break;
                }
            }

            if (isPrime) {
                count = count.add(new BigInteger("1"));
                list.add(number);
            }

            if (list.size() % 10000 == 0) {
                temp++;
                for (int i = (list.size() / 10000 - 1) * 10000; i < list.size(); i++) {
                    write(list.get(i).toString());
                }
                recording(temp + "");
                record(count.toString());
                System.out.println("已经完成" + temp + "/1000000 ^_^");
            }

            number = number.add(new BigInteger("1"));
        }

问题求解二:写素数

    public static void write(String num) {
        try (
                FileOutputStream file = new FileOutputStream("PrimeNumbers.dat", true);
                DataOutputStream fileWritter = new DataOutputStream(file)) {
            fileWritter.writeUTF(num);
            //System.out.println("Done");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

问题求解三:断点续传(读值)

//读取记录
        try (DataInputStream inputStream2 = new DataInputStream((new FileInputStream("temp.dat")));
             DataInputStream inputStream3 = new DataInputStream((new FileInputStream("doing.dat")))) {

            numStr = "10000";
            countStr = inputStream2.readUTF();
            temp = Long.parseLong((inputStream3.readUTF()));

        } catch (IOException e) {
            System.out.println("-1");
        }
        if (!(numStr.equals(""))) {
            count = new BigInteger(countStr);
            try (
                    DataInputStream inputStream = new DataInputStream((new FileInputStream("PrimeNumbers.dat")))) {
                BigInteger i = new BigInteger("0");
                for (; i.compareTo(count) < 0; i = i.add(new BigInteger("1"))) {
                    list.add(new BigInteger(inputStream.readUTF()));
                }
                number = list.get(new Integer(count.subtract(new BigInteger("1")).toString()));
                System.out.println(number);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

代码:

提示:各路大佬改为Long就好,这个基本全是类的调用,有什么不懂的可以问哟~~,有觉得要改的好的建议也建议提出来,这个程序说实话写得不好。。。。。:

public class Lab22_8Pro {
    public static void main(String[] args) {
        long temp = 0L;
        String numStr = "";
        String countStr = "";
        ArrayList<BigInteger> list = new ArrayList<>();
        BigInteger count = new BigInteger("0");
        BigInteger number = new BigInteger("2");
        BigInteger squareRoot = new BigInteger("1");

//读取记录
        try (DataInputStream inputStream2 = new DataInputStream((new FileInputStream("temp.dat")));
             DataInputStream inputStream3 = new DataInputStream((new FileInputStream("doing.dat")))) {

            numStr = "10000";
            countStr = inputStream2.readUTF();
            temp = Long.parseLong((inputStream3.readUTF()));

        } catch (IOException e) {
            System.out.println("初次启动程序");
        }
        if (!(numStr.equals(""))) {
            count = new BigInteger(countStr);
            try (
                    DataInputStream inputStream = new DataInputStream((new FileInputStream("PrimeNumbers.dat")))) {
                BigInteger i = new BigInteger("0");
                for (; i.compareTo(count) < 0; i = i.add(new BigInteger("1"))) {
                    list.add(new BigInteger(inputStream.readUTF()));
                }
                number = list.get(new Integer(count.subtract(new BigInteger("1")).toString()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

//程序主体
        while (number.compareTo(new BigInteger("10000000000")) <= 0) {
            boolean isPrime = true;

            if (squareRoot.multiply(squareRoot).compareTo(number) < 0)
                squareRoot = squareRoot.add(new BigInteger("1"));


            for (int i = 0; i < list.size()
                    && list.get(i).compareTo(squareRoot) <= 0; i++) {
                if (number.remainder(list.get(i)).equals(new BigInteger("0"))) {
                    isPrime = false;
                    break;
                }
            }

            if (isPrime) {
                count = count.add(new BigInteger("1"));
                list.add(number);
            }

            if (list.size() % 10000 == 0) {
                temp++;
                for (int i = (list.size() / 10000 - 1) * 10000; i < list.size(); i++) {
                    write(list.get(i).toString());
                }
                recording(temp + "");
                record(count.toString());
                System.out.println("已经完成" + temp + "/1000000 ^_^");
            }

            number = number.add(new BigInteger("1"));
        }
    }

    /**
     * 写数据,虽然传入的是字符串,但是写入的是BigInteger对象
     *
     * @param num 需要写入的数据
     */
    public static void write(String num) {
        try (
                FileOutputStream file = new FileOutputStream("PrimeNumbers.dat", true);
                DataOutputStream fileWritter = new DataOutputStream(file)) {
            fileWritter.writeUTF(num);
            //System.out.println("Done");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 写当前的记录
     *
     * @param num 需要写入的数据
     */
    public static void record(String num) {
        try (
                FileOutputStream file = new FileOutputStream("temp.dat");
                DataOutputStream fileWritter = new DataOutputStream(file)) {
            fileWritter.writeUTF(num);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录进度
     *
     * @param num 需要写入的数据
     */
    public static void recording(String num) {
        try (
                FileOutputStream file = new FileOutputStream("doing.dat");
                DataOutputStream fileWritter = new DataOutputStream(file)) {
            fileWritter.writeUTF(num);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值