BLOG-2

7-10周Java学习总结

前言:近几周PTA的图形类作业数量有所减少,降低了作业的难度,考试内容涉及正则表达式,字符串的比较.输入.分割代码的复用性.面向对象设计等等。题目量和难度都适中。

           期中考试主要考察了对课本知识的运用,例如多态,继承,抽象类,抽象类ArrayList的用法等等.难度题量都适中。

           实验题与期中考试考察内容大致相同,难度适中。

设计与分析

PTA作业7-1

 
7-1 sdut-String-2 识蛟龙号载人深潜,立科技报国志(II)(正则表达式)
背景省略;

请编写程序,实现如下功能:读入关于蛟龙号载人潜水器探测数据的多行字符串,从给定的信息找出数字字符,输出每行的数字之和。

提示 若输入为“2012年2月”,则该行的输出为:2014。若干个连续的数字字符作为一个整体,以十进制形式相加。

 

输入格式:

读入关于蛟龙号载人潜水器探测数据的多行字符串,每行字符不超过80个字符。

以"end"结束。

 

输出格式:

与输入行相对应的各个整数之和。

 

输入样例1:

2012年6月27日11时47分,中国“蛟龙”再次刷新“中国深度”——下潜7062米
6月15日,6671米
6月19日,6965米
6月22日,6963米
6月24日,7020米
6月27日,7062米
下潜至7000米,标志着我国具备了载人到达全球99%以上海洋深处进行作业的能力
end

 

输出样例1:

9165
6692
6990
6991
7050
7095
7099

代码如下:
import java.util.Scanner;

public class Main {
	    public static void main(String[] args){
	        Scanner in = new Scanner(System.in);
            int [] arr = new int[100];
            int j=0;
	        for(j=0;;j++)
	        {
	        	String a = in.nextLine();
	        	if(a.equals("end"))
	        		break;
	        	else {
	        		String[] s=a.split("\\D");
	                int i;
	    	        int sum = 0;
	                for(i=0;i<s.length;i++) {
	                    if(!s[i].equals(""))
	                    {
	                        int temp=Integer.parseInt(s[i]);
	                        sum+=temp;
	                    }
	                }
                    arr[j]=sum;
	        }
         }
            for(int i=0;i<j;i++)
                 System.out.println(arr[i]);
	   }
}

踩坑心得:当时对于字符串的输入没有使用nextLine()导致测试点无法通过,忽略了含有空格的情况

PTA作业7-3

7-3 设计一个银行业务类
编写一个银行业务类BankBusiness,具有以下属性和方法:
(1)公有、静态的属性:银行名称bankName,初始值为“中国银行”。
(2)私有属性:账户名name、密码password、账户余额balance。
(3)银行对用户到来的欢迎(welcome)动作(静态、公有方法),显示“中国银行欢迎您的到来!”,其中“中国银行”自动使用bankName的值。
(4)银行对用户离开的提醒(welcomeNext)动作(静态、公有方法),显示“请收好您的证件和物品,欢迎您下次光临!”
(5)带参数的构造方法,完成开户操作。需要账户名name、密码password信息,同时让账户余额为0。
(6)用户的存款(deposit)操作(公有方法,需要密码和交易额信息),密码不对时无法存款且提示“您的密码错误!”;密码正确、完成用户存款操作后,要提示用户的账户余额,例如“您的余额有1000.0元。”。
(7)用户的取款(withdraw)操作(公有方法,需要密码和交易额信息)。密码不对时无法取款且提示“您的密码错误!”;密码正确但余额不足时提示“您的余额不足!”;密码正确且余额充足时扣除交易额并提示用户的账户余额,例如“请取走钞票,您的余额还有500.0元。”。

编写一个测试类Main,在main方法中,先后执行以下操作:
(1)调用BankBusiness类的welcome()方法。
(2)接收键盘输入的用户名、密码信息作为参数,调用BankBusiness类带参数的构造方法,从而创建一个BankBusiness类的对象account。
(3)调用account的存款方法,输入正确的密码,存入若干元。密码及存款金额从键盘输入。
(4)调用account的取款方法,输入错误的密码,试图取款若干元。密码及取款金额从键盘输入。
(5)调用account的取款方法,输入正确的密码,试图取款若干元(取款金额大于余额)。密码及取款金额从键盘输入。
(6)调用account的取款方法,输入正确的密码,试图取款若干元(取款金额小于余额)。密码及取款金额从键盘输入。
(7)调用BankBusiness类的welcomeNext()方法。

输入格式:

输入开户需要的姓名、密码
输入正确密码、存款金额
输入错误密码、取款金额
输入正确密码、大于余额的取款金额
输入正确密码、小于余额的取款金额

输出格式:

中国银行(银行名称)欢迎您的到来!
您的余额有多少元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有多少元。
请收好您的证件和物品,欢迎您下次光临!

输入样例:

在这里给出一组输入。请注意,输入与输出是交替的,具体顺序请看测试类中的说明。例如:

张三 123456
123456 1000
654321 2000
123456 2000
123456 500

 

输出样例:

在这里给出相应的输出。请注意,输入与输出是交替的,具体顺序请看测试类中的说明。例如:

中国银行欢迎您的到来!
您的余额有1000.0元。
您的密码错误!
您的余额不足!
请取走钞票,您的余额还有500.0元。
请收好您的证件和物品,欢迎您下次光临!

代码如下:

import java.util.Scanner;

public class Main {
        public static void main(String[] args){
            Scanner in = new Scanner(System.in);
            String arr1 = in.nextLine();
            String[] a1=arr1.split(" ");
            Bussiness a = new Bussiness(a1[0], a1[1]);
            Bussiness.welcome();
            String arr2 = in.nextLine();
            String[] a2=arr2.split(" ");
            a.cunqian(a2[0], a2[1]);
            String arr3 = in.nextLine();
            String[] a3=arr3.split(" ");
            a.money(a3[0], a3[1]);
            String arr4 = in.nextLine();
            String[] a4=arr4.split(" ");
            a.money(a4[0], a4[1]);
            String arr5 = in.nextLine();
            String[] a5=arr5.split(" ");
            a.money(a5[0], a5[1]);
            Bussiness.welcomeNext();
       }
}
class Bussiness {
    public static String bankName = "中国银行";
    private String name;
    private String password;
    private double banlance=0;
    public Bussiness(String name , String password) {
        this.name=name;
        this.password=password;
    }
    public static void welcome() {
        System.out.println("中国银行欢迎您的到来!");
    }
    public static void welcomeNext() {
        System.out.print("请收好您的证件和物品,欢迎您下次光临!");
    }
    public void cunqian(String password , String amount) {
        double temp=Double.parseDouble(amount);
        if(!this.password.equals(password))
        {
            System.out.println("您的密码错误!");
        }
        else if(banlance<temp){
            this.banlance=temp;
            System.out.println("您的余额有"+banlance+"元。");
        }
    }
    public void money(String password , String amount) {
        double temp=Double.parseDouble(amount);
        if(!this.password.equals(password))
        {
            System.out.println("您的密码错误!");
        }
        else if(banlance<temp){
            System.out.println("您的余额不足!");
        }
        else {
            banlance -= temp;
            System.out.println("请取走钞票,您的余额还有"+banlance+"元。");
        }
    }
}

踩坑心得:这道题倒是没什么难度,刚开始没有让代码具有很高的复用性,后期将所有输出情况都放入了money类当中,大大缩短了代码的长度,提高了代码的复用性。

期中考试7-2:

7-2 点线面问题重构(继承与多态)

在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。

  • 对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。
  • 再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,输出格式如下:The Plane's color is:颜色
  • 在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。示例代码如下:
  •       element = p1;//起点Point
          element.display();
          
          element = p2;//终点Point
          element.display();
          
          element = line;//线段
          element.display();
          
          element = plane;//
          element.display();

    类结构如下图所示。

  •  

     

    其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。

    • 以下情况为无效作业
      • 无法运行
      • 设计不符合所给类图要求
      • 未通过任何测试点测试
      • 判定为抄袭
 

输入格式:

分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。

 

输出格式:

(x1,y1)
(x2,y2)
The line's color is:颜色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:长度值
The Plane's color is:颜色值

 

输入样例1:

在这里给出一组输入。例如:

5
9.4
12.3
84
Red

 

输出样例1:

在这里给出相应的输出。例如:

(5.00,9.40)
(12.30,84.00)
The line's color is:Red
The line's begin point's Coordinate is:
(5.00,9.40)
The line's end point's Coordinate is:
(12.30,84.00)
The line's length is:74.96
The Plane's color is:Red

代码如下:

 
import java.util.Scanner;

public class  Main{
        public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        double x1=0,x2=0,y1=0,y2=0;
        String color="";
        x1=in.nextDouble();
        y1=in.nextDouble();
        x2=in.nextDouble();
        y2=in.nextDouble();
        color = in.next();
        if(x1<0||x1>200||y1<0||y2>200||y1>200||y2<0||x2<0||x2>200)
        {
            System.out.println("Wrong Format");
        }
        else  
        {
            Point p1 = new Point(x1 , y1);
            Point p2 = new Point(x2 , y2);
            Line b = new Line(p1 , p2 , color);
            b.display();
        }
    }
}
class Point extends Element{
    private double x=0,y=0;
    public Point() {
        // TODO 自动生成的构造函数存根
    }
//    public void Point() {
//        
//    }
    public Point(double x,double y) {
        this.x = x;
        this.y = y;
    }
    public double getX() {
        return this.x;
    }
    public double getY() {
        return this.y;
    }
    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }
    public void display() {
        System.out.printf("(%.2f,%.2f)" , this.x , this.y);
        System.out.print("\n");
    }
}
class Line extends Element{
    private Point p1 = new Point();
    private Point p2 = new Point();
    private String color = "";
//    public Line(Point p12, Point p22, String color2) {
//        // TODO 自动生成的构造函数存根
//    }
    public Line() {
        
    }
    public Line(Point p1,Point p2 , String color) {
        this.p1 = p1;
        this.p2 = p2;
        this.color = color;
    }
    public Point getPoint1() {
        return this.p1;
    }
    public Point getPoint2() {
        return this.p2;
    }
    public void setPoint1(Point point1) {
        this.p1 = point1;
    }
    public void setPoint2(Point point2) {
        this.p2 = point2;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public double getDistance() {
        double distance = Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY()));
        
        return distance;
    }
    @Override
    public void display() {
        p1.display();
        p2.display();
        System.out.println("The line's color is:"+color);
        System.out.println("The line's begin point's Coordinate is:");
        //(5.00,9.40)
        p1.display();
        System.out.println("The line's end point's Coordinate is:");
        //(12.30,84.00)
        p2.display();
        System.out.printf("The line's length is:%.2f" , this.getDistance());
        System.out.print("\n");
        System.out.printf("The Plane's color is:"+color);
    }
}
abstract class Element {
    abstract public void  display();
}
class Plane extends Element{
    String color = "";
    public Plane() {
        
    }
    public Plane(String color) {
        this.color = color;
    }
    public String getColor() {
        return this.color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    @Override
    public void display() {
        System.out.println(color);
    }
}

踩坑心得:考试时对于抽象类和抽象方法不是很熟悉,后查阅书籍得知父类中的抽象方法在子类中重写。本题难度不大,没有什么大坑。

实验三

农夫过河

一、实验目的

1、  掌握类与对象的基本概念;

2、  掌握类的声明、创建与使用方法;

3、  掌握类的构造方法的定义与使用方法

4、  掌握类的成员变量、成员方法的定义与使用方法;

5、  理解类变量、类方法与实例变量、实例方法的区别;

6、  理解Java语言中包的概念以及package、import语句的使用;

游戏输入示例:2

游戏输出示例:

==================Please choose operation============

   ==========1:Cross the river alone===========

   ==========2:Cross the river with wolf=========

   ==========3:Cross the river with sheep============

   ==========4:Cross the river with cabbage==========

   ==========0:Quit===============

===================================================

输入样例:

Input the number(0~4):

2

Farmer has Cross  :true

Wolf is alive  :true   Wolf has Cross  :true

Sheep is alive :true   Sheep has Cross :false

Cabbage is alive:false   Cabbage has Cross:false

game over: you lose !

部分代码如下:

package 农夫过河;

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Game game = new Game();
        game.play();        
    }
}
package 农夫过河;

public class GameGui {
    public void menu()
    {
        /* 显示菜单 */
        System.out.println("==================Please choose operation============");
        System.out.println("\t==========1:Cross the river alone===========");
        System.out.println("\t==========2:Cross the river with wolf=========");
        System.out.println("\t==========3:Cross the river with sheep============");
        System.out.println("\t==========4:Cross the river with cabbage==========");
        System.out.println("\t==========0:Quit===============");   
        System.out.println("===================================================");
        System.out.println("Input the number(0~4):");
    }    

    public void showStatus(Farmer farmer, Wolf wolf, Sheep sheep, Cabbage cabbage) {
        /* 输出农夫、各种动物、物品的状态(生存、位置) */
            farmer.showStatus();
            wolf.showStatus();
            sheep.showStatus();
            cabbage.showStatus();
        }
}
package 农夫过河;

import java.util.Scanner;

public class Game {
    Wolf wolf;
    Sheep sheep;
    Cabbage cabbage;
    Farmer farmer;
    GameGui gui;
    Boat boat;
    Scanner input = new Scanner(System.in);
    Game() {
        wolf = new Wolf(input.next());
        sheep = new Sheep(input.next());
        cabbage = new Cabbage();
        farmer = new Farmer();
        gui = new GameGui();
        boat = new Boat();        
    }
    protected void play() {
        Scanner input = new Scanner(System.in);
        int choice = 0;        //用户输入选择
        boolean gameOver = false,win = false;        //游戏输赢标志,默认为false,代表未赢得游戏。
        while(!gameOver) {
            gui.menu();
            choice = input.nextInt();
            switch(choice) {
                case 0:gameOver = true;
                    break;
                case 1://农夫独过河的处理
                    boat.setCrossRiver(farmer);
                    break;
                case 2://农夫带狼的处理
                    boat.setCrossRiver(farmer , wolf);
//                    farmer.setCrossRiver();
//                    wolf.setCrossRiver();
//                    wolf.setHasCross();//对hasCross进行处理
                    break;
                case 3://农夫带羊的处理
                    boat.setCrossRiver(farmer , sheep);
//                    farmer.setCrossRiver();
//                    sheep.setCrossRiver();
//                    sheep.setHasCross();//同上
                    break;
                case 4://农夫带白菜的处理
                    boat.setCrossRiver(farmer , cabbage);
//                    farmer.setCrossRiver();
//                    cabbage.setCrossRiver();
//                    cabbage.setHasCross();//同上
                    break;
            }
            sheep.eatSheep(wolf);//狼吃羊,如果羊不在同一边,则吃不到,如果在同一边,羊被吃
            cabbage.eatCabbage(sheep);//同上 
            panduan();
            gui.showStatus(farmer,wolf,sheep,cabbage);
            if(choice==0);
            else {
                gameOver = isGameOver();
            }
        }
        win=this.hasWin();
        if(win) {
            System.out.println("game over : you win !");
        } else {
            System.out.println("game over : you lose !");
        }
        input.close();
    }
    /*
     *判断游戏是否结束
     *输入:无
     *运算:羊,白菜任一实体被吃,游戏结束,或者狼,羊,白菜均未被吃且全部渡河,游戏结束
     *输出:游戏结束--返回true,未结束--返回false
     */
     public boolean isGameOver() {
         if(sheep.isAlive()==false||cabbage.isAlive()==false) {
             return true;
         }
         if(wolf.hasCross()&&sheep.hasCross()&&cabbage.hasCross()) {
             return true;
         }
         return false;
     }
     //同上
     public boolean hasWin() {
         if(sheep.isAlive()==false||cabbage.isAlive()==false) {
             return false;
         }
         if(wolf.hasCross()&&sheep.hasCross()&&cabbage.hasCross()) {
             return true;
         }  else  {
             return false;
         }
     }
     public void panduan() {
         //判断农夫和狼,羊的位置
         if(farmer.crossRiver()==wolf.crossRiver())
             sheep.setAlive(false);
         if(farmer.crossRiver()==sheep.crossRiver())
             cabbage.setAlive(false);
     }
} 

踩坑心得:实验中存在不少细节问题,例如狼先吃羊,故羊无法再吃白菜,白菜存活,故需判断当羊进食时是否活着等等问题。本题可将农夫,狼,羊,白菜的共有属性放入一个父类中,用船来执行过河的操作,降低代码的耦合度,提高代码的复用性,方便日后修改添加新类。

改进建议:建议多提供输入样例,方便进行判断,修善代码,减少图形类题目的数量,多出些和所学契合的题目。

总结:学会了使用抽象类,抽象方法继承与多态,使用容器类,降低代码的耦合度,提高复用性。同时学会了流的运用,文件流的读入写出等等操作,学会了使用异常处理,声明,抛出,抓取异常,优雅的终止错误。对于以上学习内容,对于容器类应该进一步学习和研究熟练的使用ArrayList。希望老师能够提供答案或者上课讲一讲这些题目。

 
posted @ 2022-05-09 22:14  瓜皮将军托马斯  阅读(71)  评论(0)    收藏  举报