2023年2月Java小白学习之旅之pta作业总结报告(前三章)

发布时间 2023-03-26 17:49:00作者: 孙辰雨

前言:

       今年才学的Java,准确来说是这个学期才学的,之前上学期学过一点点c语言,在编程这条路上开了个头。前三次的题目集对我来说难度是偏高的,很多题目我自己没做完全,是不敢放在pta平台上测试的,即使测试了几遍也不敢提交。我先学习了配置JDK,后面又将JRE配置到Eclipse这个集成开发软件中去。

       前三章的知识点都是入门级的,至少前两章是。主要知识点有:Java语言规范,创建、编译和执行Java程序,学习了正确的注释、缩进和空白,块的风格,选择、循环语句的使用,数组的使用,对象与类的概念等等。题量不多,难度不大,但对于萌新来说复杂了点,是对我很头疼的事,我必须先去找网课研读,再自己写些代码调试再来做这些题目,而且目前很多题目没拿到满分,这些题目后面我又重做重新测试了,但无法提交到pta上了。

设计与分析:

这是7-1:

import java.util.Scanner;
public
class Main { public static void main(String[] args) { Scanner input = new Scanner (System.in); int i = input.nextInt(); double a=7.70; if(i>5) System.out.println("实际利率="+a*1.1+"%"); else if(i==5||i==4) System.out.println("实际利率="+"7.70"+"%"); else if(i==3||i==2) System.out.println("实际利率="+a*0.7+"%"); else if(i==1) System.out.println("实际利率="+a*0.5+"%"); else System.out.println("error"); } }

这第一题思路很简单,就一个main函数,输入和输出,还有一个if判断语句,这语句是在c语言中学过的,语法都差不多的。重点是学会了从控制台读取数据,得知Java用System.out来标准输出设备,用System.in来标准输入设备。println方法在控制台显示基本数据类型值或字符串。使用Scanner类创建一个对象,读取来自System.in的输入。

Scanner s = new Scanner (System.in);

 

这句是创建了一个Scanner类型的对象,并且把引用赋给input.Scanner类在java.util包里。刚开始的时候我习惯写的是:

java.util.Scanner s = new java.util.Scanner (System.in);

 

7-2和7-1相比没有新内容,这里就不贴上来分析了。

 

这是7-3:

public class Main
{
    public static void main(String[] args) 
    {
        java.util.Scanner s = new java.util.Scanner (System.in);
        int i = s.nextInt();int a,b;
        if(i<1 ||i>=10)
        {
       System.out.println(
"INPUT ERROR.");
     }
else { for(a=1;a<=i;a++) { for(b=1;b<=a;b++) { System.out.print(a+"X"+b+"="+a*b); if(b!=a) System.out.print("\t"); } System.out.println(); } } } }

这题是打印一个九九乘法表,之前在学习C语言的时候制作过各式各样的九九乘法表,所以知道要用一个嵌套的for循环,这里了解到Java里的条件与、条件或、条件非跟C语言中是一样的还有赋值操作符等等操作符都是一样的。

Java中命名变量和方法采用驼峰命名法,类名每个单词首字母大写,常量所有字母大写。

print是打印字符串后不换行,printf是打印字符串后换行。

public class Main{}

这行代码是定义类,类名为Main,public是修饰符,声明类是公有的,class是关键词,{}里面是类体。

public static void main(String[] args) 

这行代码是定义静态main方法,类中必须包含静态main方法,args是参数名,可自由定义,args参数是程序运行时,传递字符串,其他的基本不能改动,String[] args是声明String数组。

这是7-9:

    public static boolean isPrime(long x) {
        long m= (int) Math.sqrt(x);
        boolean flag=true;
        if (x==1) return false;
        if (x==2) return true;
        if (x%2==0) return false;
        for(long i=3;i<=m;i+=2){
            if(x%i==0)
       { flag
=false; break; } } return flag; }

 

 

 

定义了一个方法,通过定义和调用函数,组织简化代码,避免重复,避免使主函数繁琐。

public static是修饰符,boolean是返回值类型,若方法无返回值,则关键字为void。这两种方法分别称为空方法和有返回值的方法。isPrime(long x)这个是形式参数,调用方法时会给参数传递一个值,为实际参数。在方法头中必须每个参数都声明数据类型。定义了一个布尔类型的flag方便返回主方法。

 

if (isPrime(i))
       { sum
+=i; }

在主方法中这样调用isPrime方法,省略了==true。

 这是7-11:

        for (int j = 1; j <= t; j++) {
            double x = a + j * (b - a) / t ;
            sum = sum + 2*x*x+x;
        }

这道求定积分的题目我前前后后试了多种算式,答案最接近的一次也差了3位小数。百思不得其解。

 

这是7-12:

System.out.print("1/"+i+",");

Java和c语言的输出格式不一样,这里是要直接的输出的加上“”,赋值了的不用加,中间用+连接。

 这是第二次作业7-1:

        double m,n;
        m = i / 0.45359237;
        n = l / 0.0254;
        float a,b;
        a = (float) m;
        b = (float) n;

这里使用了double强转float。

当字节范围小的数据类型转换为大数据的时候,可实现直接转换;但当大数据转换为小数据时,必须加上括号写上转换的类型,否则系统报错说精度损失。

这是7-2:

int a[] = {0,0,0,0,0,0,0,0,0,0};

学会了这样定义数组。这个数组共有10个int类型元素,分别为a[0]—a[9]。

后面会这样定义数组了:

int[] myList = new int[10];

这样声明了一个数组变量myList,创建一个数组,将引用赋值给myList,后面可以直接赋值。

创建数组后元素会被赋予默认值,数值类型的数据会被赋值为0,char类型的默认值为\u0000,布尔类型的默认值为false。

 

这是7-3:

switch(a){
         case 1:
                if(d<=90)
                    s=c*10000*0.01;
                 else if(d>90&&d<=144)
                    s=c*10000*0.015;
               else if(d>144)
                s=c*10000*0.03;
          }

switch语句用于处理多条件语句,防止if嵌套次数过多。

每次case后面都要用break;否则会一直执行不退出。

default是上面case都不符合时执行的语句。

这是7-6:

            while(Math.abs(nextGuess-lastGuess)>=0.00001)
            {
                lastGuess = nextGuess;
                nextGuess = (lastGuess+n/lastGuess)/2;
            }

用了一个while循环语句,当符合条件的时候执行。

这里Math.abs用来求绝对值。数学函数有很多,sin、cos、tan分别返回弧度制的三角函数正弦、余弦、正切值,toRadians是将角度制转弧度制,toDegrees是将弧度制转角度制,PI还有E分别代表圆周率和自然对数的底。min和max返回两个数的最小值和最大值。random是生成大于等于0.0小于1.0的double类型的随机数,sqrt是开方,pow是次方。

由于精度问题,两数如果不能相等,就令它们的绝对值小于某数。

这是7-7:

for(i = 0;i < a.length();i++) {
                if(a.charAt(i) == '0' || a.charAt(i) == '1')
          ......
        }

a.length()是数组的元素的最大值。

charAt是返回指定下标位置的字符。

这是第三次7-3:

import java.util.Scanner;
public class Main{

public static void main(String[] args)
{
    Scanner s = new Scanner(System.in);
    int year = s.nextInt();
    int month = s.nextInt();
    int day = s.nextInt();
    if(checkInputValidity(year,month,day)==false)
    {
        System.out.println("Date Format is Wrong");return;
    }
    else
    getNextDate(year,month,day);
}
    
    
public static boolean isLeapYear(int year)
{
    if ((year%4==0&&year%100!=0)||(year%400==0)){
        return true;
    }
    return false;
}
public static boolean checkInputValidity(int year,int month,int day)
{
    int[] monthOfThirtyOne = new int[]{1,3,5,7,8,10,12};

    int[] monthOfThirty = new int[]{4,6,9,11};
    if(year>=1900&&year<=2000)
    {
        if (month>=1&&month<=12)
        {
    
            if (day<=0){
                return false;
            }
            if(month == 2)
            {
                if(isLeapYear(year))
                {
                    if(day<=29)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    if(day<=28)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            for(int i=0;i<7;++i){
                if (month==monthOfThirtyOne[i]){
                    // 1-31
                    if (day<=31){
                        return true;
                    }else{
                        return false;
                    }
                }
            }        
            for(int i=0;i<4;++i)
            {
                if (month==monthOfThirty[i]){
                    // 1-30
                    if (day<=30){
                        return true;
                    }else{
                        return false;
                    }
                }
        
            }    

        }
    }
    return false;
}    
public static void getNextDate(int year,int month,int day)  
{
    int[] monthOfThirtyOne = new int[]{1,3,5,7,8,10,12};
    
    int[] monthOfThirty = new int[]{4,6,9,11};
    int yearNext;
    int monthNext;
    int dayNext=day+1;
    int dayCarry=0;
    int monthCarry=0;

  
        if (month==2){
        
            if (isLeapYear(year)){
       
                if (day==29){
                    dayNext = 1;
                    dayCarry = 1;
                }
            }
        
            else{
              
                if (day==28){
                    dayNext = 1;
                    dayCarry = 1;
                }
            }
        }
    
        else{
            boolean isThirtyOne= false;
       
            for(int i=0;i<7;++i){
                if (month==monthOfThirtyOne[i]){
                    isThirtyOne = true;
                    if (day==31){
                        dayNext = 1;
                        dayCarry = 1;
                    }
                    break;
                }
            }

       
            if (!isThirtyOne){
                if (day==30){
                    dayNext = 1;
                    dayCarry = 1;
                }
            }
        }

 
        if (month+dayCarry>12){
            monthNext = 1;
            monthCarry = 1;
        }else{
            monthNext = month+dayCarry;
        }

  
        yearNext = year+monthCarry;

        System.out.println("Next day is:"+yearNext +"-"+ monthNext +"-"+ dayNext); 
}
}

说真的很多代码写的繁琐无用,都可以简化,而且格式非常不美观。

还有一点老师要求的是Date类结构,我没按结构写,虽然通过了测试,但写的不好。

这是7-4:

 

 

 

class DateUtil{
    public int[] monthOfThirtyOne = new int[]{1,3,5,7,8,10,12};
    public int[] monthOfThirty = new int[]{4,6,9,11};
    public int sum[] = new int[20];       
    
    public int year,month,day;
    public DateUtil(DateUtil d){
        this.day = d.getDay();
        this.month = d.getMonth();
        this.year = d.getYear();
        sum[1] = 31; sum[2] = 28; sum[3] = 31;  sum[4] = 30; sum[5] = 31; sum[6] = 30;sum[7] = 31; 
sum[8] = 31; sum[9] = 30; sum[10] = 31; sum[11] = 30; sum[12] = 31; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public DateUtil(int a, int b, int c){ year = a; month = b; day = c; } public boolean checkInputValidity(){ if(year>=1820&&year<=2020) { if (month>=1&&month<=12) { if (day<=0){ return false; } if(month == 2) { if(isLeapYear(year)) { if(day<=29) { return true; } else { return false; } } else { if(day<=28) { return true; } else { return false; } } } for(int i=0;i<7;++i){ if (month==monthOfThirtyOne[i]){ // 1-31 if (day<=31){ return true; }else{ return false; } } } for(int i=0;i<4;++i) { if (month==monthOfThirty[i]){ // 1-30 if (day<=30){ return true; }else{ return false; } } } } } return false; } public boolean isLeapYear(int year){ if(year % 400 == 0||year % 4 == 0 && year % 100 != 0) return true; else return false; } public DateUtil getNextNDays(int n){ for (int i = 1; i <=n; i++) { day++; if(this.isLeapYear(year)==true && month == 2){ if(day > 29){ month++; day = 1; } } else if(day > sum[month]){ day = 1; month++; if(month > 12){ month = 1; year++; } } } if(n > 365){ if(this.isLeapYear(year+1) && month > 2){ year++; n = n - 366; } else if(this.isLeapYear(year) && month <= 2){ if(month == 2 && day == 29){ day = 1; month = 3; } year++; n = n - 366; } else{ year++; n = n - 365; } } return this; }

截了中间一小段,求下n天和上n天的代码没通过测试,我觉得是其中测试点是int类型最大值放入for循环导致运行超时,我看看能不能去掉for函数令写一遍。

 

采坑心得:

if(a*a+b*b-c*c < 0.1)
                            System.out.println("Isosceles right-angled triangle");

这里写相等一直没过,是精度问题,一定要写小于一个比1小的数。

 

改进建议:

多刷题多听课,认真做笔记,及时预习复习。

 

总结:

只能说会了一点皮毛,会用Java写一点程序了,后面要慢慢精进。

数组、方法、对象和类、面向对象等等,什么都得一点点学,“十年磨一剑”,坚持下来。

建议:老师上课对基础知识做个总结,对语法格式做个统一要求。