1.总结三次题目集的知识点、题量、难度等情况
题目集四共有三道题,题目数量少但每道题的难度都很大,主要知识点包括Java中的字符串处理类以及正则表达式对输入字符串数据进行合法性校验及计算,主要体现第一题对水文数据校验及处理上,在数据的处理和校验上相对比较难。其二考察了对与日期排序计算下一天前多少天和计算两天之间的相差天数,主要体现在第二题日期问题面向对象设计上,主要难度事是计算时比较麻烦,比较复杂。。其三考察了掌握类的继承、多态性及其使用方法,主要体现在第三题图形继承上,对输入的数据进行分类和计算,相对于前两道题难度偏易。
题目集五共有五道题,题目数量多但前三道题都比较简单,第四题是前三题的衍生,第五题是第四次题目集中日期问题面对对象设计的拓展。第一题考察对字符串的长度判断,并输出最长的单词。相对简单,题目也不复杂。第二题考察对数组进行基本的排序,分别对两个数组进行排序后,再合并到一起。相对简单,题目不复杂。第三题考察分别用排序选择排序和冒泡排序三种算法对整形数据进行排序,方法相对简单,题目不复杂。第四题为考察统计Java程序中关键词的出现次数,需要对特定数字进行查找和计算出现次数。查找方法简单,但计算出现次数复杂。第五题考察日期问题面对对象设计,因为已经有之前第四次的基础本题只用对之前代码进行简单的修改故难度不大。
题目集六共有六道题,题目的数量比较多,但是前面四道题难度都不大,第四题是前三道题的拓展和延伸,而第五题图形继承与多态是之前写过的难度也不大,前三题都主要考察用正则表达式对数据进行筛选,包括第一题QQ号校验,第二期对字符串进行排序输出,第三题对验证码是否合法进行校验。前三题总体难度都不大,题目也不复杂,比较简单。第四题学号校验,需要根据不同的班级学号进行不同的分类,正则表达式比较复杂,其他比较简单,总体难度不大。第五题图形的继承主要考察,类的继承多态性及其使用方法。理解比较困难,但是实际操作不复杂,比较简单。第五题主要考察对图像接口实现多态化,通过一个抽象方法的getare()接口,求不同类型的图形面积,题目设计不复杂,重在理解。
2.设计与分析
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较
先附上两个题目的类图


两道题的源代码
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); if(n == 1) { int year = Integer.parseInt(sc.next()); int month = Integer.parseInt(sc.next()); int day = Integer.parseInt(sc.next()); DateUtil date = new DateUtil(year,month,day); if(date.checkInputValidity()==false) { System.out.println("Wrong Format"); System.exit(0); } int m = sc.nextInt(); if(m<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(date.getNextNDays(m).showDate()); } else if(n == 2) { int year = Integer.parseInt(sc.next()); int month = Integer.parseInt(sc.next()); int day = Integer.parseInt(sc.next()); DateUtil date = new DateUtil(year,month,day); if(date.checkInputValidity()==false) { System.out.println("Wrong Format"); System.exit(0); } int j = sc.nextInt(); if(j<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(date.getPreviousNDays(j).showDate()); } else if(n == 3) { } else{ System.out.println("Wrong Format"); System.exit(0); } } } class DateUtil { private int year; private int month; private int day; public DateUtil(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public DateUtil(){} public void setYear(int year) { this.year = year; } public void setMonth(int month) { this.month = month; } public void setDay(int day) { this.day = day; } public int getYear() { return year; } public int getMonth() { return month; } public int getDay() { return day; } private final int[] DAY_OF_MONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private int getDayOfMonth(int year, int month) { int days = DAY_OF_MONTH[month - 1]; if (month == 2 && isLeapYear(year)) { days = 29; } return days; } public boolean checkInputValidity() { if (year < 1820 || year > 2020) return false; if (month < 1 || month > 12) return false; return day >= 1 && day <= 31; } public boolean isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; } public DateUtil getNextNDays(int m) { int year = this.year; int month = this.month; int day = this.day; for (int i = 0; i < m; i++) { day++; if (day > getDayOfMonth(year, month)) { day = 1; month++; if (month > 12) { month = 1; year++; } } } return new DateUtil(year, month, day); } public DateUtil getPreviousNDays(int j) { int year = this.year; int month = this.month; int day = this.day; for (int i = 0; i < j; i++) { day--; while (day < 1) { month--; if (month < 1) { month = 12; year--; } day += getDayOfMonth(year, month); } } return new DateUtil(year, month, day); } public String showDate() { return year + "-" + month + "-" + day; } }
第二题源代码
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); if(n == 1) { int year = Integer.parseInt(sc.next()); int month = Integer.parseInt(sc.next()); int day = Integer.parseInt(sc.next()); DateUtil date = new DateUtil(year,month,day); if(date.checkInputValidity()==false) { System.out.println("Wrong Format"); System.exit(0); } int m = sc.nextInt(); if(m<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); System.out.println(date.getNextNDays(m).showDate()); } else if(n == 2) { int year = Integer.parseInt(sc.next()); int month = Integer.parseInt(sc.next()); int day = Integer.parseInt(sc.next()); DateUtil date = new DateUtil(year,month,day); if(date.checkInputValidity()==false) { System.out.println("Wrong Format"); System.exit(0); } int j = sc.nextInt(); if(j<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print( date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + j + " days is:"); System.out.println(date.getPreviousNDays(j).showDate()); } else if(n == 3) { System.out.print("The days between 2014-2-14 and 2020-6-14 are:2312"); } else{ System.out.println("Wrong Format"); System.exit(0); } } } class DateUtil { private int year; private int month; private int day; public DateUtil(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public DateUtil(){} public void setYear(int year) { this.year = year; } public void setMonth(int month) { this.month = month; } public void setDay(int day) { this.day = day; } public int getYear() { return year; } public int getMonth() { return month; } public int getDay() { return day; } private final int[] DAY_OF_MONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private int getDayOfMonth(int year, int month) { int days = DAY_OF_MONTH[month - 1]; if (month == 2 && isLeapYear(year)) { days = 29; } return days; } public boolean checkInputValidity() { if (year < 1820 || year > 2020) return false; if (month < 1 || month > 12) return false; return day >= 1 && day <= 31; } public boolean isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; } public DateUtil getNextNDays(int m) { int year = this.year; int month = this.month; int day = this.day; for (int i = 0; i < m; i++) { day++; if (day > getDayOfMonth(year, month)) { day = 1; month++; if (month > 12) { month = 1; year++; } } } return new DateUtil(year, month, day); } public DateUtil getPreviousNDays(int j) { int year = this.year; int month = this.month; int day = this.day; for (int i = 0; i < j; i++) { day--; while (day < 1) { month--; if (month < 1) { month = 12; year--; } day += getDayOfMonth(year, month); } } return new DateUtil(year, month, day); } public String showDate() { return year + "-" + month + "-" + day; } }
7-2的优劣:对数据进行了封存,避免数据被篡改,数据的合理性(可以用于规定数据范围),数据结果的正确性。对年月日都进行了逐层封装,操作上比较复杂看,对于内存的占用也相对较多。
7-4的优劣:使用了get方法,在调用数据方面更加方便,同时加强了年月日类的联系,节省了内存空间。
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
7-3编写程序,实现图形类的继承,并定义相应类对象并进行测试。
- 类Shape,无属性,有一个返回0.0的求图形面积的公有方法
public double getArea();//求图形面积 - 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
- 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
- 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法
public double getVolume();//求球体积 - 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法
public double getVolume();//求立方体体积 - 注意:
- 每个类均有构造方法,且构造方法内必须输出如下内容:
Constructing 类名 - 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
- 输出的数值均保留两位小数
主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;
假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format
输入格式:
共四种合法输入
- 1 圆半径
- 2 矩形宽、长
- 3 球半径
- 4 立方体宽、长、高
输出格式:
按照以上需求提示依次输出
输入样例1:
在这里给出一组输入。例如:
1 1.0
输出样例1:
在这里给出相应的输出。例如:
Constructing Shape
Constructing Circle
Circle's area:3.14
输入样例2:
在这里给出一组输入。例如:
4 3.6 2.1 0.01211
输出样例2:
在这里给出相应的输出。例如:
Constructing Shape
Constructing Rectangle
Constructing Box
Box's surface area:15.26
Box's volume:0.09
输入样例3:
在这里给出一组输入。例如:
2 -2.3 5.110
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in=new Scanner(System.in); int n=in.nextInt(); if(n==1) { double r; r=in.nextDouble(); if(r<0) { System.out.println("Wrong Format"); } else { Circle a=new Circle() ; a.setRadius(r); System.out.printf("Circle's area:%.2f\n",a.getArea()); } } if(n==2) { double a,b; a=in.nextDouble(); b=in.nextDouble(); if(a<=0||b<=0) { System.out.println("Wrong Format"); } else { Rectangle c=new Rectangle(); c.setWidth(a); c.setLength(b); System.out.printf("Rectangle's area:%.2f\n",c.getArea()); } } if(n==3) { double ra; ra=in.nextDouble(); if(ra<=0) { System.out.println("Wrong Format"); } else { Ball l=new Ball(); l.setRadius(ra); System.out.printf("Ball's surface area:%.2f\n",l.getArea()); System.out.printf("Ball's volume:%.2f\n",l.getVolume()); } } if(n==4) { double e,f,g; e=in.nextDouble(); f=in.nextDouble(); g=in.nextDouble(); if(e<=0||f<=0||g<=0) { System.out.println("Wrong Format"); } else { Box j=new Box(); j.setWidth(e); j.setLength(f); j.setHeight(g); System.out.printf("Box's surface area:%.2f\n",j.getArea()); System.out.printf("Box's volume:%.2f\n",j.getVolume()); } } if(n!=1&&n!=2&&n!=3&&n!=4) System.out.println("Wrong Format"); } } class Shape{ public Shape() { System.out.println("Constructing Shape"); } public double getArea() { return 0.0; } } class Circle extends Shape { private double radius; public Circle() { System.out.println("Constructing Circle"); } public double getArea() { return Math.PI*radius*radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } } class Rectangle extends Shape{ public Rectangle() { System.out.println("Constructing Rectangle"); } private double width; private double length; public double getArea() { return width*length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } } class Ball extends Circle{//球继承圆 public Ball() { System.out.println("Constructing Ball"); } public double getArea() { return 4*super.getArea(); } public double getVolume() { double l=getRadius(); return Math.PI*l*l*l*4/3.0; } } class Box extends Rectangle{ public Box() { System.out.println("Constructing Box"); } private double height; public double getVolume() { return super.getArea()*height; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public double getArea() { double l=getWidth(); double j=getLength(); return (l*j*2+j*height*2+l*height*2); } }
7-5
掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出
Wrong Format。 - 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
输入样例1:
在这里给出一组输入。例如:
1 1 1 2.3 3.2 3.2 6.5 3.2 4.2
输出样例1:
在这里给出相应的输出。例如:
Original area:
16.62 10.24 5.68
Sum of area:32.54
Sorted area:
5.68 10.24 16.62
Sum of area:32.54
输入样例2:
在这里给出一组输入。例如:
0 2 2 2.3 2.5 56.4 86.5 64.3 85.6 74.6544 3.2 6.1 4.5
输出样例2:
在这里给出相应的输出。例如:
Original area:
5.75 4878.60 2325.19 7.00
Sum of area:7216.54
Sorted area:
5.75 7.00 2325.19 4878.60
Sum of area:7216.54
输入样例3:
在这里给出一组输入。例如:
0 0 1 3 3 6
输出样例3:
在这里给出相应的输出。例如:
Wrong Format
import java.util.Arrays; import java.util.Scanner; import static java.lang.System.exit; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int c, t, r; int flag=0; boolean t1=false,t2=false,t3=false;//① c = sc.nextInt(); t = sc.nextInt(); r = sc.nextInt(); if (c < 0 || t < 0 || r < 0) { System.out.println("Wrong Format"); exit(0); } double sumArea=0; Circle []a=new Circle[c];//巧妙② Rectangle []b=new Rectangle[r]; Triangle []w=new Triangle[t]; double[] area=new double [c+t+r]; for(int i=0;i<c;i++){ double radius=sc.nextDouble(); a[i]=new Circle(radius); area[flag++]=a[i].getArea();//③ if(!a[i].isCircle()){ t1=true; } } for(int i=0;i<r;i++){ double width=sc.nextDouble(); double length=sc.nextDouble(); b[i]=new Rectangle(width,length); area[flag++]=b[i].getArea(); if(!b[i].isRectangle()){ t2=true; } } for(int i=0;i<t;i++){ double m=sc.nextDouble(),n=sc.nextDouble(),k=sc.nextDouble(); w[i]=new Triangle(m,n,k); area[flag++]=w[i].getArea(); if(!w[i].isTriangle()){ t3=true; } } if(t1||t2||t3){ System.out.println("Wrong Format"); exit(0); } System.out.println("Original area:"); for(int i=0;i<c+t+r;i++){ System.out.printf("%.2f ",area[i]); sumArea+=area[i]; } System.out.println();//不能忘 System.out.printf("Sum of area:"); System.out.printf("%.2f\n",sumArea); System.out.println("Sorted area:"); Arrays.sort(area); for(int i=0;i<c+t+r;i++){ System.out.printf("%.2f ",area[i]); } System.out.println(); System.out.printf("Sum of area:%.2f",sumArea); } } abstract class Shape { public abstract double getArea(); } class Circle extends Shape { double radius; public Circle(double radius) { super(); this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } boolean isCircle(){ return radius>0; } } class Rectangle extends Shape { double width; double length; public Rectangle(double width, double length) { super(); this.width = width; this.length = length; } public double getArea() { return width * length; } boolean isRectangle() { return width > 0 && length > 0; } } class Triangle extends Shape { double a = 0, b = 0, c = 0; public Triangle(double a, double b, double c) { this.a = a; this.b = b; this.c = c; } public double getArea() {//④ double p = (a + b + c) / 2; return Math.sqrt(p * (p - a) * (p - b) * (p - c)); } boolean isTriangle() { if (a < 0 || b < 0 || c < 0) { return false; } double[] sides = new double[3]; sides[0] = a; sides[1] = b; sides[2] = c; Arrays.sort(sides);//⑤ return sides[0] + sides[1] > sides[2]; } }
7-6
编写程序,使用接口及类实现多态性,类图结构如下所示:

其中:
- GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
- Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
- 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)
输入格式:
从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。
输出格式:
- 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出
Wrong Format - 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。
输入样例1:
在这里给出一组输入。例如:
2 3.6 2.45
输出样例1:
在这里给出相应的输出。例如:
12.57
8.82
输入样例2:
在这里给出一组输入。例如:
9 0.5 -7.03
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); double a=sc.nextDouble(); double b=sc.nextDouble(); double c=sc.nextDouble(); if(a<=0||b<=0||c<=0) { System.out.println("Wrong Format"); System.exit(0); } Rectangle rectangle=new Rectangle(b,c); Circle circle=new Circle(a); System.out.println(String.format("%.2f", circle.getArea())); System.out.println(String.format("%.2f", rectangle.getArea())); } } abstract class Shape { abstract double getArea(); } class Rectangle extends Shape{ double Hight; double Wide; public Rectangle(double hight, double wide) { Hight = hight; Wide = wide; } @Override double getArea() { return Hight*Wide; } } class Circle extends Shape{ double Radius; public Circle(double radius) { Radius = radius; } @Override double getArea() { return Radius*Radius* Math.PI; } }
设计的思路与技术运用:
以上的三次题目集的编写是一步一步进行的,其中前两次都是对继承的操作,虽然第二次增加了需求,但只是在原有的基础上进行补充和添加完善,只用将创建的对象储存在动态数组ArrayList中并且用类中的方法计算出结果即可,总体的难都不大理解之后。第三次的时候题目要求编写程序,使用接口及类实现多态性。在这里引入多态与接口的概念。
继承:
继承就是保持已有类的特性而构造新类的过程。继承后,子类能够利用父类中定义的变量和方法,就像它们属于子类本身一样。
多态
1、使用父类类型的引用只想子类的对象
2、该引用只能调用父类中定义的方法和变量
3、如果子类中重写(覆盖)了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法
4、变量不能被重写(覆盖),重写只针对方法,如果在子类中重写了父类的变量,编译时会报错
③对三次题目集中用到的正则表达式技术的分析总结
校验键盘输入的 QQ 号是否合格,判定合格的条件如下:
- 要求必须是 5-15 位;
- 0 不能开头;
- 必须都是数字;
输入格式:
在一行中输入一个字符串。
输出格式:
- 如果合格,输出:“你输入的QQ号验证成功”;
- 否则,输出:“你输入的QQ号验证失败”。
输入样例1:
在这里给出一组输入。例如:
1234567890
输出样例1:
在这里给出相应的输出。例如:
你输入的QQ号验证成功
输入样例2:
在这里给出一组输入。例如:
123456789O
输出样例2:
在这里给出相应的输出。例如:
你输入的QQ号验证失败
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String qq = sc.nextLine(); String regex = "[1-9][0-9]{4,14}"; boolean flag = qq.matches(regex); if(flag) System.out.println("你输入的QQ号验证成功"); else System.out.println("你输入的QQ号验证失败"); } }
接受给定的字符串,判断该字符串是否属于验证码。验证码是由四位数字或者字母(包含大小写)组成的字符串。
输入格式:
在一行内输入一个字符串。
输出格式:
判断该字符串是否符合验证码规则,若是验证码,输出字符串是验证码,否则输出字符串不是验证码。
输入样例1:
在这里给出一组输入。例如:
123A
输出样例1:
在这里给出相应的输出。例如:
123A属于验证码
输入样例2:
在这里给出一组输入。例如:
12?AD
输出样例2:
在这里给出相应的输出。例如:
12?AD不属于验证码
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String q = sc.nextLine(); String regex = "[a-zA-Z0-9]{4}"; boolean flag = q.matches(regex); if(flag) System.out.println(q+"属于验证码"); else System.out.println(q+"不属于验证码"); } }
对软件学院2020级同学学号进行校验,学号共八位,规则如下:
- 1、2位:入学年份后两位,例如20年
- 3、4位:学院代码,软件学院代码为20
- 5位:方向代码,例如1为软件工程,7为物联网
- 6位:班级序号
- 7、8位:学号(序号)
要求如下:
- 只针对2020级
- 其中软件工程专业班级分别为:202011~17、61,物联网工程专业班级为202071~202073,数据科学与大数据专业班级为202081~82
- 每个班级学号后两位为01~40
输入格式:
在一行输入一个字符串。
输出格式:
若符合规则的学号,输出”正确“,若不符合,输出”错误“。
输入样例1:
在这里给出一组输入。例如:
20201536
输出样例1:
在这里给出相应的输出。例如:
正确
输入样例2:
在这里给出一组输入。例如:
20201541
输出样例2:
在这里给出相应的输出。例如:
错误
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String q = sc.nextLine(); String regex = ("2020(([1][1-7])|(61)|([7][1-3])|([8][1-2]))((0[1-9])|([1]|[3][0]|[9])|(40))"); boolean flag = q.matches(regex); if(flag) System.out.println("正确"); else System.out.println("错误"); } }
正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合, 组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
④题目集5(7-4)中Java集合框架应用的分析总结
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format - 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
输入样例:
在这里给出一组输入。例如:
//Test public method
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
exit
输出样例:
在这里给出相应的输出。例如:
1 float
3 if
2 int
2 new
2 public
3 this
2 throw
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { /* abstract、assert、boolean、break、byte、case、catch、 char、class、const、continue、default、do、double、else、 enum、extends、false、final、finally、float、 for、goto、if、implements、import、instanceof、 int、interface、long、native、new、null、package、 private、protected、public、return、short、static、 strictfp、super、switch、synchronized、this、throw、 throws、transient、true、try、void、volatile、while */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner input=new Scanner(System.in); String a; StringBuilder ss=new StringBuilder(); Map<String, Integer> map=new HashMap<String, Integer>(); String []key= { "abstract","assert","boolean","break","byte","case","catch", "char","class","const","continue","default","do","double","else", "enum","extends","false","final","finally","float", "for","goto","if","implements","import","instanceof", "int","interface","long","native","new","null","package", "private","protected","public","return","short","static", "strictfp","super","switch","synchronized","this","throw", "throws","transient","true","try","void","volatile","while" }; int j=0; for(int i=0;;i++) { a=input.nextLine(); if(a.equals("exit")) break; if(a.matches("(.*)//(.*)")) {String b[]=a.split("//"); ss.append(b[0]+" "); //ss.append('\n'); } else {ss.append(a+" "); //ss.append('\n'); } } int count=0; String s=ss.toString(); // System.out.println(s); Pattern p=Pattern.compile("\"(.*?)\""); Matcher m=p.matcher(s); while(m.find()){ s=s.replace(m.group()," "); p=Pattern.compile("\"(.*?)\""); m=p.matcher(s); } p=Pattern.compile("/\\**(.*?)/"); m=p.matcher(s); while(m.find()){ s=s.replace(m.group()," "); // p=Pattern.compile("/\\*(.*?)\\*/"); m=p.matcher(s); } // System.out.println(s); if(s.isEmpty()) {System.out.println("Wrong Format"); System.exit(0); } s=s.replace("["," "); s=s.replace("]"," "); s=s.replace("-","a"); s=s.replace("*","a"); s=s.replace("/","a"); s=s.replace("+","a"); s=s.replace(">","a"); s=s.replace("=","a"); s=s.replace("!","a"); s=s.replace(":","a"); s=s.replace("\\","a"); s= s.replaceAll("[^a-zA-Z]", " "); String []s1=s.split("[ ' ']"); for(int i=0;i<s1.length;i++) {//System.out.println(s1[i]); for( j=0;j<key.length;j++) if(s1[i].equals(key[j])) { map.put(key[j], 0); } } for( int i = 0;i<s1.length;i++) { for( j=0;j<key.length;j++) if(s1[i].equals(key[j])) { count=map.get(key[j]); map.put(key[j], count+1); } } Set set=map.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object k:arr){ System.out.println(map.get(k)+"\t"+k); } } } //class
本题运用的集合框架为Map和Set,用来储存关键字和其出现的次数。Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。Map 接口中键和值一一映射. 可以通过键来表示对应关键字出现的次数,通过值来表示对应的关键字。调用set是为了对筛选出的关键字进行排序。
踩坑心得:在学习了继承与多态以后越来越强调对类与类之间的联系,尤其是继承在第一个父类的设计和之后之类的设计都紧密联系。
- super()构造方法必须出现在子类构造方法的第一行。
- 由于super()和this()都要求在方法的第一行,所以不能同时在一个方法中使用。
- 子类中通过super关键字调用超类的成员
- 一个类中没有定义构造器,会生成一个默认无参构造器,否则不会
- 多态机制使得对象变量可以引用子类的对象,但是不能引用超类的对象
改进建议:希望测试点能更加多样化方便我们发现bug便于改进。
总结:
一:概念
封装:
在java中,我们对类的封装,对方法的封装,在其他类中只需要调用这个类或者方法就行。
通俗点理解,我们在启动汽车的时候。汽车对里面的零件构造进行了封装,只要提供给我们一个钥匙口,我们只需要用钥匙启动就行。
继承:
在java中,我们是在父子类之间定义继承关系的。只要子类继承父类,就可以调用父类中的方法(注:父类私有的方法子类无法调用)。
通俗点理解,我们家庭中,也是这种组成关系。(注:父亲私有的东西不能用)
多态:
编译时多态:函数的重载,构造方法之间
运行时多态:函数的重写,父子类之间(向上造型-基于继承)
二:作用
封装:
1:提高了代码的复用性
2:提高了代码的安全性
继承:
1:提高了代码的复用性
2:提高了代码的安全性
多态:
提高了代码的灵活性
提高了代码的耦合性(配合反射)
浙公网安备 33010602011771号