JMU-JAVA-2023-实验一


前言

大概仅限jmu-lw老师的java实验。

注意看题目,不要照搬,老师会变换题目照搬会露馅,会登上实验课ppt公开处刑。不过应该都是换汤不换药。了解了类似的题目,很快就能写好符合题设的代码。

如果发现有错误,欢迎指出,谢谢啦!

也非常非常欢迎提出更好的代码!超级感谢!


易错点

这个来自于老师批阅完实验后的总结评语。

从批改情况看,大部分同学都能够完成实验要求,主要有如下几个方面有待改进:

1)实验报告中截图问题(不要整个屏幕截);实验报告应该包含设计思想、主要算法、关键代码、测试及结果、实验小结等;

关于设计思想,爱莫能助,我至今也不清楚,在最后一部分给出了一种可能性。这个并非评判重点,老师要看很多份作业,两三分钟看完一个人的情况下,老师不会一个个都打开项目代码查看(注意,实验二还是实验三会打开代码一个个人看),主要是看实验报告。实验错误分析是老师评判是否抄袭的重点。不过,批改作业速度快 + 错误分析容易捏造 + 后期摆烂人太多 —> 老师心理预期降低 —> 评判标准降低 == 浑水摸鱼概率较大,不过,见下面第六点批语。

2)提交文件不完整(提交到教学平台上的除了实验报告外,还要有该实验相关的源代码工程,甚至还要可能的配置说明等);

一整个项目复制下来即可。上课有讲的,至于是不是在大家都交完实验报告截止提交之前讲就不清楚了。会出现老师提醒的时候已经改不了的坑。

3)Java类命名不规范,如小写、汉字、匿名包等,第一个实验就不追究,后面的实验请大家注意,不然一律判0分;

类名要大驼峰命名法。

一般建包(包名全小写),差不多就像是文件夹的功能吧,然后在文件夹里面创建类。可能不准确这个图片,各自有各自的偏好。也有人一道题一个项目的。

...

4)模块化封装不合理;

模块化封装应该遵循单一职责原则(一个类应该只负责一项明确的功能或职责)和高内聚(高内聚的类或模块应该包含相关的功能,各成员之间具有强关联,共同协作完成一项任务或目标)低耦合(一个类或模块的修改不会对其他类或模块造成过多的影响,避免修改一个模块引起连锁反应)原则,确保模块功能清晰、相互独立,并且能够实现高效的代码组织、重用和维护。

5)逻辑思维或计算思维不够严谨;

可能是第三题没有用埃氏筛,第五题没有用迭代法。边界数值出错。逻辑漏洞。值类型不对 … …

6)抄袭比较严重,同学之间代码雷同或抄袭网络代码,第一个实验很多轻微的暂不追究,但同学们也应该知道学习是为了你自己,而不是为老师、为分数!


第一题第二题(略)


第三题


题干

3.筛法求素数

编写一个程序,从键盘读取正整数n,使用筛法求不大于n的所有素数(或称质数,Prime Number),并逐个打印出来。输出结果为:

n=10

The prime numbers are 2,3,5,7

注意:处理控制台输入,请参考课件中相关内容(使用Scanner的nextLine()或nextInt());可以学习查询jdk文档,Integer类的parseInt方法,将字符串转换成int型。

(1)编写函数

编写public static void printPrimeNumbers(int[] n)方法,将不大于n的每个素数输出;

编写public static int[] getPrimeNumbers(int n)方法,将每个不大于n的素数放入数组,并返回。方法原型定义参考如下(逻辑代码需要自行填充!方法签名不能修改,但代码不限定):

public static int[] getPrimeNumbers(int n){

int[] result = new int[n];

//一系列处理代码

return result;

}

(2)编写测试代码

在main方法中输入n,调用getPrimeNumbers方法获取素数数组,再调用printPrimeNumbers方法输出这些素数。


代码实现

public class TestPrime {
    public static int[] getPrimeNumbers(int n){
        int cnt=0;
        boolean [] isPrime = new boolean[n+1]; //可以改成byte数组 用0 1表示 节省空间
        for(int i = 2;i <= n;i++){
            isPrime[i]=true;
        }

        for(int i = 2;i <= n; i++){      //这里有更好的方法 可以优化到nlogn
            if(!isPrime[i]) continue;   
            for(int j=i*2;j<=n;j+=i){
                isPrime[j] = false;
            }
            cnt++;						//不过为了计数来减少存储空间 没有优化
        }

        int [] result = new int[cnt];
        for(int i=2,j=0;i<isPrime.length;i++){
            if(isPrime[i]){
                result[j++]=i;
            }
        }
        return result;
    }

    public  static void printPrimeNumbers(int []n){
        System.out.print("The prime number");
        if(n.length==0){
            System.out.print(" is null. ");
        }else if(n.length==1){
            System.out.print(" is ");
        }
        else{
            System.out.print("s are ");
        }

        for(int i=0;i<n.length;i++){
            System.out.print(n[i]);
            if(i < n.length-1)
                System.out.print(", ");
        }
    }

    public static void main(String[] args) {
        Scanner s=new Scanner(System.in);
        System.out.print("n = ");
        String str =s.nextLine();
        int range = Integer.parseInt(str);

        printPrimeNumbers(getPrimeNumbers(range));
    }
}

关于思考题

*(3)思考

当n比较大时(如100,000,000),分析算法的瓶颈,并给出改进的策略!

瓶颈

很明显,会存在合数被重复标记的情况,比如10在2的5倍标记过,在5的2倍标记过。

针对合数,我们如果只用他的最小素因子倍数来筛,时间复杂度就可以改进一些。

改进

欧拉筛。

代码实现
public static int[] getPrimeNumbers(int n) {
    boolean[] isPrime = new boolean[n + 1];
    int[] primes = new int[n + 1];
    int primeCount = 0;

    for (int i = 2; i <= n; i++) {
        if (!isPrime[i]) {
            primes[primeCount++] = i;
            isPrime[i] = true;
        }
        for (int j = 0; j < primeCount && primes[j] * i <= n; j++) {
            isPrime[primes[j] * i] = true;
            if (i % primes[j] == 0) {         //保证用他的最小素因子倍数来筛的关键
                break;
            }
        }
    }

    int[] result = new int[primeCount];
    System.arraycopy(primes, 0, result, 0, primeCount);
    return result;
}

第四题(略)


第五题


题干

5.求e的近似值

自然对数底数e是一个超越数,是一个无限不循环小数,它的值约为2.718281828459…。数学上,e定义为(1+1/n)n的极限(n趋于无穷大)。此外,e也可以定义为:1/0!+1/1!+1/2!+…+1/n!+…,更适合计算机迭代算法。

要求:使用迭代法,且误差控制在10-6以内。


代码实现

public class E {
    public static void main(String[] args) {
        System.out.println(e(1e-10));
    }

    private static double e(double err){
        //err:误差控制
        double e = 1.0;
        double f = 1.0;
        int i = 1;
        while(true){
            f *= i++;
            e += 1.0 / f;
            if(1.0 / f < err) break;
        }
        return e;
    }

    //非迭代法
    private static double e(int n){
        double e = 1.0;
        double f = 1.0;
        for(int i = 1;i <= n;i++){
            f *= i;
            e += 1.0 / f;
        }
        return e;
    }
}


实验报告

仅仅提供一种可能性,不是模板

代码和报告并非配套的。可能上面的代码来自一个人,报告又是别的人的。

报告开篇

中间


结尾


在这里插入图片描述


结语

不知道这些博客是否有用。能否帮到人。希望不要误人子弟。

请,务必擦亮眼睛,在看这些文章的时候。如果我的程序有bug,我们都没有看出来,那会是一个判定抄袭的扣分项

写下这系列文章的原因目的挺多的,按下不表。不知道能否写完这个系列,或者说不知道这个系列会留存多久。也许题目大改就删了?随缘吧。

接下来或许不会有实验报告的部分了或者减少出镜率?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值