JAVA前三次PTA作业总结

一、关于java&面向对象

       这学期是我第一次接触Java,这门课的学习对我而言极具挑战性,因为自己的C语言学的很一般,所以学习Java之前还有着相对来说畏惧的情绪,但是这个阶段的学习,我并没有感觉到特别吃力反而感觉自己学的还可以,并且有很高的兴趣,可能是它相较于C语言来说有些地方相对方便,并且编辑软件IDEA极其好用,这门课是面向对象的程序设计思想,相对之前的学习有很大的不同之处。

       此阶段是我的Java入门学习,以下均为个人感受,共分为作业概况,设计与分析,踩坑心得,改进建议以及作业总结,也是对自己这个阶段的学习做一个小总结。

 


 

二、前言

第一次作业

第一次作业的题目分别是:

    • 7-1 计算两个数的和
    • 7-2 电话键盘字母数字转换
    • 7-3 成绩分级管理
    • 7-4 计算税率
    • 7-5 计算钱币
    • 7-6 使用一维数组求平均值
    • 7-7 对多个整数进行排序
    • 7-8 判断三角形类型

运用知识点

    • 应用Scanner类完成输入,import java.util.Scanner。
    • 在PTA中包含main函数的核心类都是Main,例如public class Main。
    • main函数的声明格式为public static void main(String[] args)。
    • 应该用System.out.println()和System.out.print()完成输出。
    • 运用nextInt()等等通过键盘输入变量。
    • charAt()获取字符位置。
    • 数组的运用。
    • 例如用import java.util.Arrays和Arrays.sort(a)使用内置排序函数。
    • 大部分命令语句和C没有太大区别。

题目难度

这个是我我的Java第一次作业,尽管是最基本的基本语法内容,但是处理起来仍然花费了不少的时间去应对,包括对软件的调试以及一些基本操作语句的了解。

总而言之,前几题了解基本输入输出最后后面写题过程还是相对流畅许多的。

第二次作业

第二次作业的题目分别是:

    • 7-1 IP地址转换 
    • 7-2 合并两个有序数组为新的有序数组
    • 7-3 判断闰年及星期几
    • 7-4 求下一天
    • 7-5 求前N天

运用知识点

    • 除了基础知识点之外,对象的建立和方法的调用。
    • 利用boolean进行判断。
    • 用数组存储月份天数。

题目难度

 难度不高,但是if语句确实不能写太多,不然改起来头昏眼花,使用数组处理问题很好用。

第三次作业

第三次作业的题目分别是:

    • 7-1 创建账户类Account
    • 7-2 定义日期类
    • 7-3 一元多项式求导(类设计)

运用知识点

    • 对象的创建。
    • 对象属性与方法的调用。
    • 涉及到了类的封装性,多个类的写法。
    • 运用正则表达式。
    • 字符串截取的表达方式。

题目难度

 7-1 初次处理有点不知所措,但是稍微了解之后处理起来较为轻松;7-2 和第二次作业类似,创建类对象属性方法调用等处理起来也十分轻松;7-3 是真的坐牢,就感觉难度跨度还是比较大的,正则表达式学习了很久以及import java.util.regex.Matcher 和 import java.util.regex.Pattern 的使用现在也没搞的太明白,判断到后面自己都感觉有点乱的不知所措,是非常有挑战性的题,但是最后一个测试点还存在bug,对指数为1的x的单项式求导后的正数结果前面本来应该输出+号与其它单项式连接,但测试例子却没这个问题。

 


 

三、作业分析(包括设计分析,踩坑心得和改进建议)


 

第一次题目集:7-8:

1、 设计与分析

(1)设计:

源代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
     Scanner input=new Scanner(System.in);
     double a=input.nextDouble();
     double b=input.nextDouble();
     double c=input.nextDouble();
        
       if(a>=1&&a<=200&&b>=1&&b<=200&&c>=1&&c<=200){
         if((a+b)>c&&(a+c)>b&&(b+c)>a&&(a-b)<c&&(a-c)<b&&(b-c)<a&&(b-a)<c&&(c-a)<b&&(c-b)<a){
           if(a==b&&b==c){System.out.print("Equilateral triangle");}
            
             if(a==b&&a!=c){
                if(a*a+b*b-c*c<0.1) //不要用a*a+b*b==c*c
                    System.out.print("Isosceles right-angled triangle");
                 else
                    System.out.print("Isosceles triangle");
             }
             
             if(a==c&&a!=b){
                 if(a*a+c*c-b*b<0.1) 
                    System.out.print("Isosceles right-angled triangle");
                 else
                    System.out.print("Isosceles triangle");
             }
                 
             if(b==c&&b!=a){
                 if(b*b+c*c-a*a<0.1) 
                    System.out.print("Isosceles right-angled triangle");
                 else
                    System.out.print("Isosceles triangle");
             }
                 
                 
             else if(a!=b&&b!=c&&a!=c){
                 if(a*a+b*b==c*c || a*a+c*c==b*b || c*c+b*b==a*a){System.out.print("Right-angled triangle"); }
                 else
                     System.out.print("General triangle");
             }
 
           }
       else
         System.out.print("Not a triangle");
         }
       else
         System.out.print("Wrong Format"); 
       }
    }

  我首先判断了三角形的合法性,如何根据边的关系去进一步判断三角形的类型。

 

(2)分析:

这道题要求根据输入的三角形的三条边判断所能构成的三角形的类型,如果输入数据非法,则输出“Wrong Format”; 如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; 如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; 如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; 如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; 如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; 如果输入数据合法且能够成一般三角形,则输出“General triangle”。

因此我只用判断是否合法进行下一步的判断类型,如果非法直接输出“Wrong Format”。

 

 SourceMonitor 复杂度分析 

 

 

 

 

2、踩坑心得:if语句使用过多导致报错时自己判断括号匹配及其吃力痛苦;然后是 double的精度问题,由于Java中的小数计算不是那么准确,会出现精度丢失的问题,导致一开始在判断直角三角形                         的时候采用相减得0得方法并不可用,无法过测试点,不要用a*a+b*b==c*c去判断直角三角形,应当用a*a+b*b-c*c<0.1去进行判断。

 

3、改进建议:因为这次代码写的时间较早,因此大量使用了if else语句判断,没有将判断内容方法化所以如 SourceMonitor所示的这样圈复杂度较高。并且三角形的类型合法性可以把三条边放到一                         个数组里通过一个排序函数去判断。

 


 

第二次题目集:7-4:

1、 设计与分析

(1)设计:

源代码

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        int year= input.nextInt();
        int month= input.nextInt();
        int day= input.nextInt();
        if(checkInputValidity( year, month, day)==false)
            System.out.print("Wrong Format");
        else
            nextDate ( year, month, day);
        }
        
        public static boolean isLeapYear(int year) {//判断year是否为闰年,返回boolean类型 
            
            if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
                
                return true;
                
            }
            else{
                
                return false;
            }
        }
        //判断输入日期是否合法,返回布尔值
        public static boolean checkInputValidity(int year,int month,int day){
            if(year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31) {
                if(isLeapYear(year)==false&&month==2&&day>28) {
                    
                    return false;
                }
                if(month==4||month==6||month==9||month==11) {
                    if(day==31) 
                        return false;
         
                }
                
                if(isLeapYear(year)==true) {
                    if(month==2&&day>29) 
                    {
                        
                        return false;
                    }
                    
                }
                else if(isLeapYear(year)==false) {
                    if(month==2&&day>28) 
                        return false;
                }
                 return true;
            }
            else 
                return false;
        }

        public static void nextDate (int year,int month,int day) {//求输入日期的下一天
            
              if(month==1||month==3||month==5||month==7||month==8||month==10) {
             if(day==31) {
                 System.out.println("Next date is:"+year+"-"+(month+1)+"-"+1);
             }
             else
                 System.out.println("Next date is:"+year+"-"+month+"-"+(day+1));
         }
         else if(month==12) {
             if(day==31) {
                 System.out.println("Next date is:"+(year+1)+"-"+1+"-"+1);
             }
             else
                 System.out.println("Next date is:"+year+"-"+month+"-"+(day+1)); 
         }
         if(isLeapYear(year)==false) {
             if(month==2) {
                 if(day==28) {
                     System.out.println("Next date is:"+year+"-"+(month+1)+"-"+1);
                 }
                 else
                     System.out.println("Next date is:"+year+"-"+month+"-"+(day+1));
             }
         }
         else if(isLeapYear(year)==true) {
             if(month==2) {
                 if(day==29) {
                     System.out.println("Next date is:"+year+"-"+(month+1)+"-"+1);
                 }
                 else
                     System.out.println("Next date is:"+year+"-"+month+"-"+(day+1)); 
             }
         }
         if(month==4||month==6||month==9||month==11) {
             if(day==30) {
                 System.out.println("Next date is:"+year+"-"+(month+1)+"-"+1);
             }
             else
                 System.out.println("Next date is:"+year+"-"+month+"-"+(day+1));
         }
     }
            
    }

 该作业的要求输入年月日的值(均为整型数),输出该日期的下一天;首先设计非法输入,令boolean checkInputValidity = true;如果输入范围不在题目要求的范围内,在此注意闰年1月,2月,7    月,8月和每月的边界情况以及闰年的最后一天,返回false,则输出("Wrong Format")

 

(2)分析:

三个方法依次判断了日期的合法性,闰年以及日期的下一天,使用了多个if语句进行分类判断。

 根据PowerDesigner的类图显示,该题只有一个类,但利用了三个方法:

  • public static void main(String[] args);//主方法
  • public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
  • public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
  • public static void nextDate(int year,int month,int day) ; //求输入日期的下一天

 

SourceMonitor 复杂度分析 

 

 

 

 

2、踩坑心得:特殊月份的特殊情况没有想到;多个if语句的判断及其容易产生错误,并且报错进行调试时十分头大,但是足够细心的话问题还是不大的。

 

3、改进建议:if以及else的语句完全没必要,可以写一个数组存放每个月的天数int[] a=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};再做一个判断去修改闰年二月份的天数

if(isLeapYear(year)==false)    a[2] = 28;过程可以简便很多,我通过此题的踩坑在下一题对自己的代码进行了优化。

 

 


 

第二次题目集:7-5:

1、 设计与分析

(1)设计:

源代码

import java.util.Scanner;

public class Main{

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        int year= input.nextInt();
        int month= input.nextInt();
        int day= input.nextInt();
        int n= input.nextInt();
        
        if(checkInputValidity(year,month,day,n)==true)
        {
            lastDate(year,month,day,n);

        }
        else
            System.out.print("Wrong Format");

        
        }
        
        public static boolean isLeapYear(int year) {//判断year是否为闰年,返回boolean类型 
            
            if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
                
                return true;
                
            }
            else{
                
                return false;
            }
        }
        //判断输入日期是否合法,返回布尔值
        public static boolean checkInputValidity(int year,int month,int day,int n){
            if(n>=-10&&n<=10) {
            if(year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31) {
                if(isLeapYear(year)==false&&month==2&&day>28) {
                    
                    return false;
                }
                if(month==4||month==6||month==9||month==11) {
                    if(day==31) 
                        return false;
         
                }
                
                if(isLeapYear(year)==true) {
                    if(month==2&&day>29) 
                    {
                        
                        return false;
                    }
                    
                }
                else if(isLeapYear(year)==false) {
                    if(month==2&&day>28) 
                        return false;
                }
                 return true;
            }
            else 
                return false;
        }
            else 
                return false;
        }
        public static void lastDate(int year,int month,int day,int n){
            int[] a=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
            
            if(isLeapYear(year)==false)
                a[2] = 28; 
            
            day=day-n;
            
            if(n>0) {
                while(day<=0) {
                    month--;
                    if (month==0){
                        year--;
                        month=12;
                    }
                    day=day+a[month];
                }
            }
            
            else if (n<0){
                 while (day>a[month]) {
                     day=day-a[month];
                     month++;
                     if (month==13){
                         month=1;
                         year++;
                     }
                 }
             }
             System.out.print( n + " days ago is:"+year+"-"+month+"-"+day);
         }
     }
    

 这道题基本与上题一致,同样先合法性的判断,再判断闰年以及求前n天。

 

(2)分析:

根据PowerDesigner的类图显示,该题只有一个类,但利用了三个方法:

        • public static void main(String[] args);//主方法
        • public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
        • public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
        • public static void lastDate(int year,int month,int day,int n) ; //求输入日期的前n天

 

SourceMonitor 复杂度分析 

 

 

 

  

2、踩坑心得:吸取了上一题的教训,将if和else语句替换成了数组表示,并且利用了while循环进行了天数的加减,感触良多,数组真好用啊,特别清晰简洁。

 

3、改进建议:感觉合法性以及前n天的求解应该还有更简单方便的表示方法但是之前偷懒没有再去进行思考,以后类似的题还可以做的更简洁一些。

 


 

第三次题目集:7-2:

1、 设计与分析

(1)设计:

源代码

import java.util.Scanner;
public class Main {
    //主函数
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Date date = new Date();
        date.year = input.nextInt();
        date.month = input.nextInt();
        date.day = input.nextInt();

        date.getnextDate(date.year,date.month,date.day);
    }

    //Date类
    public static class Date {
        private int year;
        private int month;
        private int day;
        int[] mon_maxnum = new int[]{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        public Date(int year, int month, int day) {
            this.year = year;
            this.month = month;
            this.day = day;
        }

        public Date() {
            int year, month, day;
        }

        public int getYear() {//getter
            return year;
        }

        public int getMonth() {
            return month;
        }

        public int getDay() {
            return day;
        }

        public void setYear(int year) {//setter
            this.year = year;
        }

        public void setMonth(int month) {
            this.month = month;
        }

        public void setDay(int day) {
            this.day = day;
        }

        public static boolean isLeapYear(int year) {//判断year是否为闰年
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
                return true;
            else
                return false;
        }

        public static boolean checkInputValidity(int year, int month, int day) {//判断输入日期是否合法
            int[] mon_maxnum = new int[]{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
            if (!isLeapYear(year))
                mon_maxnum[2] = 28;
            if (year >= 1900 && year <= 2000 && month > 0 && month <= 12 && day <= mon_maxnum[month] && day > 0)
                return true;
            else
                return false;

        }

        public static void getnextDate(int year, int month, int day) { //得到下一天
            int[] mon_maxnum = new int[]{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

            if (!isLeapYear(year))
                mon_maxnum[2] = 28;
            if (checkInputValidity(year, month, day)) {

                day = day + 1;

                while (day > mon_maxnum[month]) {
                    day = day - mon_maxnum[month];
                    month++;
                    if (month == 13) {
                        month = 1;
                        year++;
                        day = 1;
                    }
                }
                System.out.println("Next day is:" + year + "-" + month + "-" + day);
            }
            else
                System.out.println("Date Format is Wrong");

        }
    }
}

 

该作业的要求是定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数。

此题由提供的类图可知,需要我们重新构建一个新的Date类,Date date=new Date(year,month,day);并且对year month day 三个属性进行封装变为私有属性,同时构造有参和无参来进行传输数据,用get和set方法将其进行调用。

 

        public int getYear() {//getter
            return year;
        }

        public int getMonth() {
            return month;
        }

        public int getDay() {
            return day;
        }

        public void setYear(int year) {//setter
            this.year = year;
        }

        public void setMonth(int month) {
            this.month = month;
        }

        public void setDay(int day) {
            this.day = day;
        }

 

(2)分析:

和第二次作业基本类似,算是老题新解吧,因为和第二次作业基本一样,所以我直接就使用了之前的类,同时结合了第一题的封装以及类的调用。

 

根据PowerDesigner的类图显示,直观地看出,该题涉及了两个类Date和Main,利用了多个方法:

 

 

SourceMonitor 复杂度分析 

 

 

 

2、踩坑心得:我通过对数组的使用加深,除了得到下一天我对判断日期的合法性的判断同样也使用了数组,真的相比较于if,else语句简化了许多也不容易判断失误。

 

3、改进建议:getter及setter方法,以及一些类方法的调用还是有点生疏,都是在参照第三次作业的第一题在照猫画虎但是成效还是可以的;至于其他的修改及方式,本人还在努力学习当中。

 


 

第三次题目集:7-3:

1、 设计与分析

(1)设计:

源代码

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Scanner in = new Scanner(System.in);
        String input = in.nextLine().replace(" ", "");// 读取并去除空格
        String output = "";
        int type = judge(input);

        if(type == 5)//如果是多项式
            output = result4(input);
        else if(type == 0)//如果都不符合即输入错误
            System.out.println("Wrong Format");
        else//如果是四种单项情况
            output = Result(type, input);

        System.out.print(output);

    }

    // 判断是否为常数
    public static boolean constant(String input) {
        if (input.matches("(-|\\+)?\\d*"))
            return true;
        else
            return false;
    }

    // 判断是否为幂函数
    public static boolean singleItem1(String input) {
        if (input.matches("([^*]x\\^[+-]?[1-9]\\d*)"))
            return true;
        else
            return false;
    }

    // 判断是否为只含系数单项式
    public static boolean singleItem2(String input) {
        if (input.matches("([\\+|-]?[1-9]\\d*\\*x)|([\\+|-]?x)"))
            return true;
        else
            return false;
    }

    // 判断有指数和系数的单项式
    public static boolean singleItem3(String input) {
        if (input.matches("([\\+|-]?[1-9]\\d*\\*x\\^[\\+|-]?[1-9]\\d*)|(([\\+|-]?x\\^[\\+|-]?[1-9]\\d*))"))
            return true;
        else
            return false;
    }

    // 判断多项式是否正确
    public static boolean polynomial(String input) {
        if (input.matches(
                "(([\\+|-]?[1-9]\\d*\\*x\\^[\\+|-]?[1-9]\\d*)|(([\\+|-]?x\\^[\\+|-]?[1-9]\\d*))|(x\\^[\\+|-]?[1-9]\\\\d*)|([\\+|-]?[1-9]\\d*\\*x)|([\\+|-]?x)|((-|\\+)?\\d*))([-|\\+](([\\+|-]?[1-9]\\d*\\*x\\^[\\+|-]?[1-9]\\d*)|(([\\+|-]?x\\^[\\+|-]?[1-9]\\d*))|(x\\^[\\+|-]?[1-9]\\d*)|([\\+|-]?[1-9]\\d*\\*x)|([\\+|-]?x)|((-|\\+)?\\d*)))*"))
            return true;
        else
            return false;
    }

    // 判断类型
    public static int judge(String input) {

        int a = 0;

        if (constant(input))// 指数
            a = 1;
        else if (singleItem1(input))// 幂函数
            a = 2;
        else if (singleItem2(input))// 只含系数的单项式
            a = 3;
        else if (singleItem3(input))// 含系数和指数项
            a = 4;
        else if (polynomial(input))// 多项式
            a = 5;
        return a;

    }

    // 选择性求导
    public static String Result(int type, String input) {
        String output = "";
        switch (type) {
            case 1:
                output = "0";
                break;// 常数项求导
            case 2:
                output = result1(input);
                break;// 幂函数求导
            case 3:
                output = result2(input);
                break;// 只含系数项求导
            case 4:
                output = result3(input);
                break;// 含系数和指数项求导
        }
        return output;

    }

    // 获取输入表达式的系数
    public static int inputCoefficient(String input) {
        int tempt = input.indexOf('x');
        int a = 0;
        if (input.charAt(tempt - 1) == '*')
            a = Integer.parseInt(input.substring(0, tempt - 1));
        else if(tempt == 0)
            a =  1;
        else if(input.charAt(tempt - 1) == '-')
            a =  -1;
        return a;

    }

    // 获取输入表达式的指数
    public static int inputExponent(String input) {
        int tempt = input.indexOf('^');
        return Integer.parseInt(input.substring(tempt + 1));
    }

    // 计算输出表达式的系数
    public static int outputCoefficient(String input) {
        return inputCoefficient(input) * inputExponent(input);
    }

    // 计算输出表达式的指数
    public static int outputExponent(String input) {
        if(inputExponent(input) == 1)
            return 1;//如果指数是1则返回1
        else
            return inputExponent(input) - 1;
    }

    // 拆分多项式
    public static String[] separate(String input) {
        String[] stringArray = new String[30];

        Matcher m = Pattern.compile(
                "([\\+|-]?[1-9]\\d*\\*x\\^[\\+|-]?[1-9]\\d*)|(([\\+|-]?x\\^[\\+|-]?[1-9]\\d*))|(x\\^[\\+|-]?[1-9]\\d*)|([\\+|-]?[1-9]\\d*\\*x)|([\\+|-]?x)|((-|\\+)?\\d*)")
                .matcher(input);

        for (int i = 0; m.find(); i++) {
            stringArray[i] = m.group();
        }

        return stringArray;
    }

    // 计算幂函数的导数
    public static String result1(String input) {
        int tempt = input.indexOf('^');
        if (Integer.parseInt(input.substring(tempt + 1)) == 1)
            return "x";// 如果输入为x^1,返回x
        if (Integer.parseInt(input.substring(tempt + 1)) == -1)
            return "-x";// 如果输入为x^1,返回x
        String a = Integer.parseInt(input.substring(tempt + 1)) + "x^"
                + (Integer.parseInt(input.substring(tempt + 1)) - 1);
        return a;
    }

    // 计算只含系数单项式的导数
    public static String result2(String input) {
        String a = inputCoefficient(input)+"";
        return a;

    }

    // 计算有系数和指数单项式的求导结果
    public static String result3(String input) {
        String a;
        if(outputCoefficient(input) == 1 && outputExponent(input) == 1)
            a = "x";//指数系数都为1
        else if (outputCoefficient(input) == 1)
            a = "x^" + outputExponent(input);//系数为1
        else if (outputCoefficient(input) == -1)
            a = "-x^" + outputExponent(input);//系数为-1
        else if (outputExponent(input) == 1)
            a = outputCoefficient(input) + "*x";//指数为1
        else
            a = outputCoefficient(input) + "*x^" + outputExponent(input);
        return a;
    }

    // 计算多项式的求导结果
    public static String result4(String input) {
        String[] stringArray = new String[30-1];
        stringArray = separate(input);// 将字符串拆分并存入字符串数组
        int type = 0;
        String output;
        //先将第一个项传进字符串
        if(Result(judge(stringArray[0]), stringArray[0]).equals("0"))
            output = "";
        else
            output = Result(judge(stringArray[0]), stringArray[0]);
        //将后续项项传进字符串
        for (int i = 1; stringArray[i] != null; i++) {
            //判断类型
            type = judge(stringArray[i]);

            stringArray[i] = stringArray[i].replaceAll("\\s+", "-");
            //跳过空项
            if (stringArray[i].equals("-"))
                continue;
                //跳过0项
            else if (Result(type, stringArray[i]).equals("0"))
                continue;
                //相加
            else if (output == "")
                output +=  Result(type, stringArray[i]);
            else if (Result(type, stringArray[i]).charAt(0) =='-')
                output +=  Result(type, stringArray[i]);
            else
                output += "+" + Result(type, stringArray[i]);
        }
        return output;
    }

}

 

 这题主要是使用类与对象编写程序对简单多项式的导函数进行求解,并且还要满足以下条件:

    • 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
    • 当输出结果第一项系数符号为“+”时,不输出“+”;
    • 当指数符号为“+”时,不输出“+”;
    • 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。

我是将多项式切割开之后然后在不同的部分分别进行求导然后再相加,我分为了以下几种情况:

 

 // 判断是否为常数
    public static boolean constant(String input)
 // 判断是否为幂函数
    public static boolean singleItem1(String input)
// 判断是否为只含系数单项式
    public static boolean singleItem2(String input) 
 // 判断有指数和系数的单项式
    public static boolean singleItem3(String input)

 

(2)分析:

首先是对输入的多项式进行拆分,拆分成为常数项,幂函数项,只含系数的单项式和有指数系数的单项式

对不同的部分用正则表达式进行判断,分别求导,最后将求导结果合并在一起,最后将输出的多项式的合法性进行判断。

 

// 判断类型
    public static int judge(String input) {

        int a = 0;

        if (constant(input))// 指数
            a = 1;
        else if (singleItem1(input))// 幂函数
            a = 2;
        else if (singleItem2(input))// 只含系数的单项式
            a = 3;
        else if (singleItem3(input))// 含系数和指数项
            a = 4;
        else if (polynomial(input))// 多项式
            a = 5;
        return a;
    }

// 拆分多项式
    public static String[] separate(String input) {
        String[] stringArray = new String[30];

        Matcher m = Pattern.compile(
                "([\\+|-]?[1-9]\\d*\\*x\\^[\\+|-]?[1-9]\\d*)|(([\\+|-]?x\\^[\\+|-]?[1-9]\\d*))|(x\\^[\\+|-]?[1-9]\\d*)|([\\+|-]?[1-9]\\d*\\*x)|([\\+|-]?x)|((-|\\+)?\\d*)")
                .matcher(input);

        for (int i = 0; m.find(); i++) {
            stringArray[i] = m.group();
        }

        return stringArray;
    }

    // 选择性求导
    public static String Result(int type, String input) {
        String output = "";
        switch (type) {
            case 1:
                output = "0";
                break;// 常数项求导
            case 2:
                output = result1(input);
                break;// 幂函数求导
            case 3:
                output = result2(input);
                break;// 只含系数项求导
            case 4:
                output = result3(input);
                break;// 含系数和指数项求导
        }
        return output;
    }

 

SourceMonitor 复杂度分析 

 

 

 

2、踩坑心得:因为判断条件太多,所以到后面可能自己到分不太清楚分割开的单项式的判定求导结果到底对不到可能跳到了别的判定上;分割的还是不够好,判定出来很乱;正则表达式掌握的不够好,可能不同的部分的                           正则表达式有些问题导致有测试点过不去;最后的结果拼接也有一些小问题在报错;没有想到最后一个测试点居然有bug,就是5x+6x这种,输出56,而不是5+6;反正这题自己能力还是不大行所以做的比较                           乱尽管有思路但是完成的不够好。

 

3、改进建议:可以利用多项式的连接符号“+”“-”的位置利用charAt()去找到它们的位置然后进行分割;分割开的各不同类型的单项式的求导还可以再优化;连接时的符号问题可以放在分割的单项式求导里面解决比较不容易出                          错感觉,对正则表达式的了解还需要加深,很多地方的判定都出了问题还可以再修正改进。

 


 

 

、PTA其他题目的踩坑心得和改进建议

关于其他的题目的话,其实上面的五道典型且有难度的题目已经涵盖了我大部分的心得和感受,其他题目的改进建议也和上面大同小异,所以我便不再赘述。

 


 

 

五、总结

    1. 第一次作业虽然题目较多,但都是基础题,做起来还是挺顺畅,只要会Java的基本格式的输入和输出就可以轻松解决。
    2. 第二次作业主要是通过严密的逻辑来考虑现实生活中,平年润年对于不同月份日期加减的限制要求,从而选择一个正确且便捷的方式进行加减计算,整体来说,除了要注意复杂度,别用太多的if,else语句去判断,用数组加while语句去判断可以轻松的多。
    3. 第三次作业,虽然只有三道题,相对之前的两次作业,却要花费更多的时间去学习和思考,首先是到类的增加以及封装性,但根据题目的提示,再去CSDN上寻找类似的题型去学习,搭好所要求的框架后,还是可以较为轻松的解决的。当然,这部分涉及到了很多新知识点,对前两道题进行深度学习和理解对于后续的学习还是很有必要的。重点是第三题,首先是正则表达式的书写就让我有点头痛,去CSDN上学了好久还是不怎么会表达,其次就是选择分割的位置的选取以及求导类型的判断,期间与同学交流了解他们的想法,有些很优质的想法真的很让人眼界大开很佩服题目还能这样子去解这道题。
    4. 总而言之,经过这三次PTA作业,我对Java的学习和了解有了很大的变化,从完全不懂到可以分析解题写代码优化,但是我发现自己的的编程能力和独立思考的能力还是不够并且我的思维方式也不够严谨简便,在后续的学习中,我会与同学多多交流,去CSDN查找有关资料,相信自己以后会对Java及其语法的使用进行更深入的认知与学习。

 

posted @ 2021-10-15 12:53  tian_n  阅读(199)  评论(0)    收藏  举报