Java基础-求十万以内的质数

Java实现质数判断并优化性能
该代码示例展示了如何用Java计算一定范围内的质数,并通过使用Math.sqrt优化算法性能。primeNumber1()和primeNumber2()方法分别计算100以内和100000以内的质数,通过减少内层循环次数和提前跳出循环来提高效率。
/**
 * @author 苗晓强
 * @date 2023/7/25 23:45
 * 求一定范围内的质数
 * 质数定义:除了1和它本身,没有其他的公约数
 */
public class PrimeNumberTest {
    public static void main(String[] args) {
        //求 100 以内的质数
        primeNumber1();
        //求 100000 以内的质数
        primeNumber2();
    }

    private static void primeNumber2() {
        int count = 0;
        long start = System.currentTimeMillis();
        for (int i = 2; i <= 100000; i++){
            boolean flag = true;
            //Math.sqrt(i) 缩小内层循环的范围,是提高性能的一个关键点
            for (int j = 2; j <= Math.sqrt(i); j++){
                if (i % j == 0){
                    flag = false;
                    //查到有 除了 1 和自身能整除的数,就跳出循环,是提高性能的另一个关键点
                    break;
                }
            }
            if (flag){
                count++;
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("查询100000以内的质数,共" + count + "个,共耗时:" + (end - start) + "毫秒!");
    }

    private static void primeNumber1() {
        int count = 0;
        long start = System.currentTimeMillis();
        for (int i = 2; i <= 100; i++){
            boolean flag = true;
            for (int j = 2; j < i; j++){
                if (i % j == 0){
                    flag = false;
                }
            }
            if (flag){
                count++;
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("查询100以内的质数,共" + count + "个,共耗时:" + (end - start) + "毫秒!");
    }
}

<think>嗯,用户想用Java1到100以内质数。首先,我得回忆一下质数的定义。质数是指大于1的自然数,除了1和它本身外,不能被其他自然数整除的数。那也就是说,像2、3、5、7这些都是质数,而4、6、8这些就不是,因为它们能被除了1和自身之外的数整除。 接下来,我需要考虑如何用Java来实现这个功能。可能需要遍历1到100之间的每个数,然后对每个数判断是否为质数。那怎么判断一个数是否是质数呢?常见的办法是试除法。对于当前数n,检查从2到sqrt(n)之间的所有整数,看是否有能整除n的数。如果有,就不是质数;否则就是。 不过这里需要注意几个点。首先,1不是质数,所以应该直接排除。2是最小的质数,也是唯一的偶数质数。然后,对于大于2的偶数,可以直接跳过,因为它们肯定能被2整除,不是质数。这样可以减少循环次数,提高效率。 那具体步骤应该是怎样的呢?大概的思路是: 1. 外层循环遍历1到100的所有数字。 2. 对于每个数字n,首先检查是否小于等于1,如果是,跳过。 3. 如果n是2,直接认为是质数。 4. 如果n是偶数,跳过。 5. 对于剩下的奇数,检查从3到sqrt(n)之间的所有奇数,看是否能整除n。如果有,就不是质数,否则是。 接下来,代码结构应该怎么写?可能用两个循环,外层循环处理每个数,内层循环检查因数。为了提高效率,可以优化内层循环的条件,比如只检查到sqrt(n),并且跳过偶数。 比如,判断n是否为质数的函数可能长这样: public static boolean isPrime(int n) { if (n <= 1) { return false; } if (n == 2) { return true; } if (n % 2 == 0) { return false; } for (int i = 3; i <= Math.sqrt(n); i += 2) { if (n % i == 0) { return false; } } return true; } 然后在主函数里循环调用这个函数,输出结果。 不过,有没有可能哪里出错了?比如,循环条件是否正确?比如,i应该从3开始,每次加2,只检查奇数。而Math.sqrt(n)可能需要转换为int,或者直接让i的平方不超过n。或者有没有可能漏掉某些情况? 比如,当n是9的时候,sqrt(9)=3,所以循环会检查i=3,这时候9%3==0,正确返回false。而当n=25时,i会到5,25%5==0,也正确。看起来没问题。 另外,在输出的时候,应该收集所有的质数,或者直接在内层循环判断时打印。比如,主函数可以这样写: public static void main(String[] args) { for (int i = 1; i <= 100; i++) { if (isPrime(i)) { System.out.print(i + " "); } } } 这样应该就能输出1到100之间的所有质数了。不过需要测试一下,比如2是否正确被包含,3、5等是否正确,以及像9、15这样的合数是否被排除。 可能还需要注意,当n是平方数时,比如25,是否能正确判断。因为循环中的i会到sqrt(n),即5,这时候25%5==0,会被正确判断为非质数。 那有没有更高效的方法?比如埃拉托斯特尼筛法(Sieve of Eratosthenes),这种方法可能在大范围内更高效,但对于1到100来说,试除法已经足够快,而且实现简单。 不过用户可能只是想了解基本的实现方法,所以先给出试除法的方案,如果有需要再介绍筛法。或者可以提一下两种方法的区别。 那现在,整理思路,写出分步骤的解答,并给出代码示例。同时需要注意代码的正确性,比如边界条件,比如n=2的情况是否被正确处理,n=1是否正确排除,以及循环中的条件是否正确。 最后,确保代码符合Java语法,比如类名、方法修饰符等。例如,完整的代码可能如下: public class PrimeNumbers { public static void main(String[] args) { for (int i = 1; i <= 100; i++) { if (isPrime(i)) { System.out.print(i + " "); } } } public static boolean isPrime(int n) { if (n <= 1) { return false; } if (n == 2) { return true; } if (n % 2 == 0) { return false; } for (int i = 3; i <= Math.sqrt(n); i += 2) { if (n % i == 0) { return false; } } return true; } } 这样应该就能正确输出1到100之间的所有质数了。测试一下,比如输出结果应该包括2,3,5,7,11...97等。 不过,可能还可以进一步优化内层循环的条件。比如,使用i*i <=n来代替Math.sqrt(n),因为计算平方根可能比较耗时。例如: for (int i = 3; i * i <= n; i += 2) { 这样可能更高效,尤其是在处理大数的时候。不过对于n=100来说,差别不大。但作为良好的编程习惯,这样写可能更好。 所以,可能将循环条件改为i*i <=n。 综上,最终的代码应该正确,并且高效地找出所有质数。</think>以下是Java1-100以内质数的分步实现方法: ### 质数定义 质数(素数)是大于1的自然数,且除了1和它本身外没有其他因数的数。 ### 实现思路 1. **遍历数字**:检查1-100的每个数字 2. **排除非质数**: - 所有小于2的数字都不是质数 - 所有偶数(除2外)都不是质数 3. **试除法验证**:对于奇数n,只需验证是否能被3到√n之间的奇数整除 ### 完整代码实现 ```java public class PrimeNumberFinder { public static void main(String[] args) { System.out.println("1-100以内质数:"); for (int num = 2; num <= 100; num++) { // 从2开始检查 if (isPrime(num)) { System.out.print(num + " "); } } } // 质数判断方法 private static boolean isPrime(int n) { if (n <= 1) return false; if (n == 2) return true; // 2是唯一的偶质数 if (n % 2 == 0) return false; // 排除其他偶数 // 只需检查3到√n之间的奇数 for (int i = 3; i * i <= n; i += 2) { if (n % i == 0) { return false; } } return true; } } ``` ### 执行结果 ``` 1-100以内质数: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 ``` ### 代码优化说明 1. **跳过偶数处理**:通过`i += 2`只检查奇数因子 2. **平方根优化**:使用`i * i <= n`代替`Math.sqrt()`,避免浮点运算 3. **提前终止**:发现任何因子立即返回false ### 算法复杂度 该实现的时间复杂度为$O(n\sqrt{n})$,适用于小范围(如n ≤ 10^6)的质数筛选。对于更大范围的质数查找,推荐使用埃拉托斯特尼筛法(时间复杂度$O(n\log{\log{n}})$)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值