PTA题目集4-6的总结
前言
PTA题目集4
知识点主要有正则表达式的复杂用法,类与类之间的关系(聚合),类与类之间的继承关系,题量3道,题量比较少,但难度为三次习题集中最难的。
PTA题目集5
知识点主要有字符串的分割,数组里数的三种排序(插入,选择,冒泡排序),List接口,类与类之间的关系(聚合),题量5道,题量适中,难度相对于上次简单一点。
PTA题目集6
知识点主要有正则表达式的简单用法,类的封装,继承与多态,图形接口,字符排序,题量6道,题量适中,难度相对于上次简单一点。
设计与分析
题目集4 7-2
Source Monitor生成图内容

Power Designer类图

题目集5 7-5
Source Monitor生成图内容

Power Designer类图

(1)两种日期类聚合设计的优劣比较:
从圈复杂度看,两种聚合方法基本上没什么区别;
题目集4的相对于题目集5的写法更加复杂一点,题目集4的年,月,日是一层一层聚合起来的,如果需要得到年份得用到
this.getDay().getMonth().getYear().getValue(),
需要通过日,月,年一层层调用,而题目集5得到年份只需要
this.getYear(),
明显可以看出题目集5的更简单一点,而且题目集5理解起来也更加好理解。
题目集4 7-3
Source Monitor生成图内容

Power Designer类图

题目集6 7-5
Source Monitor生成图内容

Power Designer类图

题目集6 7-6
Source Monitor生成图内容

Power Designer类图

(2)对三种渐进式图形继承设计思路与技术运用的分析
1.设计思路:这三题有一个很明显的特点就是继承,继承主要继承父类的属性和方法,在设计父类的时候找所有类相同的属性和方法作为父类的属性和方法,如果子类需要重写该方法直接
@Override
重写该方法,还需其他属性的话,在super()后再继续添加属性,这能使代码更加简便,思路更清楚;
2.技术运用:
(1)封装:每个类的属性均设置为私有的,再通过公共的(public)方法:getxxx()和setxxx()实现对该属性的操作,这样通过隐藏对象的属性来保护对象内部的状态,提高代码的可用性和可维护性;
例如:题目集4 7-3将矩形的长,宽设置为私有的,通过get,set获取
class Rectangle extends Shape{
private double width;
private double length;
public double getterWidth() {
return width;
}
public void setterWidth(double width) {
this.width=width;
}
public double getterLength() {
return length;
}
public void setterLength(double length) {
this.length=length;
}
}
(2)继承:通过extend关键字或implements关键字让类与类之间产生继承的关系,super关键字来实现对父类成员的访问,用来引用当前对象的父类,this关键字指向自己的引用。子类可以接受父类非私有属性以及方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性,继承的出现让类与类之间产生了子父类关系,提供了多态度前提条件;
例如:题目集4 7-3重写分类算面积的方法
@Override
public double getArea()
{
double area;
area=width*length;
return area;
}
(3)多态:使用多态的一个很重要的前提是使用了继承,使用多态方法调用时之前必须保证父类中有该方法,可以对所有类的对象做通用处理;
(4)接口:Interface关键字用来声明一个接口,在类声明中,Implements关键字放在class声明后面。
例如:题目集6 7-6
用interface关键字声明GetArea的接口
public interface GetArea{
public double getArea();
}
static class Circle implements GetArea{
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea()
{
return Math.PI*radius*radius;
}
}
(3)对三次题目集中用到的正则表达式技术的分析总结
题目集4 7-1
1.用于时间年月日时分的格式检验:
[1-9]\\d{3}/([1-9]|1[0-2])/([1-9]|[1-2][0-9]|3[0-1]) ([02468]|20|22|24|1[02468]):00
格式为“年/月/日 时:分”,其中年份取值范围为[1,9999],“月”与“日”为一位数时之前不加“0”,日期与时间之间有一个空格,“时”与“分”之间采用冒号分隔(英文半角),“时”为一位数时之前不加“0”,“分”始终保持两位,且始终为“00”。注意:“时”数必须是24小时进制中的偶数值。
2.目标水位、实际水位、流量格式检验:
([1-9][0-9]{0,2}\\.[0-9]{1,3})|([1-9][0-9]{0,2})
格式均为实型数,取值范围为[1,1000), 小数点后保留1-3位小数或无小数(也无小数点)
3.目标开度、实际开度格式检验:
[1-9]\\.\\d{2}
题目集5 7-4
1.匹配代码中//:
.*//.*
2.匹配代码中“”
\"(.*?)\"
3.匹配代码中/* */
/\\*.+\\*/
题目集6 7-1
QQ号校验(要求必须为5-15位,0不能开头,必须都是数字)
String r = "[1-9]\\d{4,14}";
题目集6 7-2
验证码校验 (验证码是由四位数字或者字母(包含大小写)组成的字符串)
String r = "[0-9A-Za-z]{4}$";
题目集6 7-4
学号校验学号共八位,规则如下:
1、2位:入学年份后两位,例如20年
3、4位:学院代码,软件学院代码为20
5位:方向代码,例如1为软件工程,7为物联网
6位:班级序号
7、8位:学号(序号)
if(str.matches("2020(11|12|13|14|15|16|17|61|71|72|73|81|82)[0-3][0-9]")==true) {
if(str.matches("2020(11|12|13|14|15|16|17|61|71|72|73|81|82)00")==true)
System.out.println("错误");
else
System.out.println("正确");
}
else
System.out.println("错误");
}
以上为这次作业运用到的所有正则表达式;
总结正则表达式的用法:
\ :将下一字符标记为特殊字符、文本、反向引用或八进制转义符,例如:"n"匹配字符"n"。"\n"匹配换行符。序列"\\"匹配"\","\("匹配"("。
\w:匹配任何字类字符(字母,数字,下划线)与“[A-Za-z0-9_]”等效。
\\\\:表示普通反斜杠。
^: 匹配输入字符串开始位置
$:匹配输入字符串结尾的位置。
*:零次或多次匹配前面的字符或子表达式。
+:一次或多次匹配前面的字符或子表达式,等效于{1,}。
?:零次或一次匹配前面的字符或子表达式,等效于{0,1}。
{n}:n 是非负整数,正好匹配 n 次。
{n,}:n 是非负整数,至少匹配 n 次。
{n,m}:m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。
[a-z]:匹配指定范围内的任何字符。例如:
"[a-z]"
匹配“a”到“z”范围内的任何小写字母。
[^a-z]:匹配不在指定范围内的任何字符。例如:
"[^a-z]"
匹配“a”到“z”范围内的任何小写字母。
\d:数字字符匹配,等效于
[0-9]
\D:非数字字符匹配,等效于
[^0-9]
(4)Java集合框架应用分析总结
题目集 5 7-4
Source Monitor生成图内容

Power Designer类图

集合框架主要用于存储数据,与数组的区别在集合的长度是可以改变的;
Iterator接口:
Iterator接口,用于遍历集合元素的接口。
例如
Iterator<KeyWords> itr = list.iterator();
while(itr.hasNext()) {
KeyWords e = itr.next();
System.out.println(e.showStatus());
}
List集合:
List
list.add(e)加方法
//如果关键字次数不为0,则增加到list列表中
if(keyWords.getTimes() != 0) {
list.add(keyWords);
}
list.remove(index)删除方法
list.get(index)获取方法
set与add比较
list.set(1, b);// 将索引位置为1的对象e修改为对象b
list.add(2, c);// 将对象c添加到索引位置为2的位置
String str = list.toString();将list转化成字符串
arr = list.toArray();将list转化成数组
采抗心得
题目集4 7-2
问题:在计算两个日期之间的天数差时,得到的结果一直都与正确答案相差1天,在闰年判断的时候因为if-else没有判断对,导致得不到正确答案,改进后的代码:
public DateUtil getNextNDays(int n){//下n天
int year,month,day;
int arr[] = {31,28,31,30,31,30,31,31,30,31,30,31};
year=this.getDay().getMonth().getYear().getValue();
month=this.getDay().getMonth().getValue();
day=this.getDay().getValue();
if(this.getDay().getMonth().getYear().isLeapYear()==true) {
arr[1]=29;
}
for(int i=0;i<n;i++) {
Year t = new Year(year);
if(t.isLeapYear()) {
arr[1]=29;
}
else {
arr[1]=28;
}
day+=1;
if(day>arr[month-1]) {
day=1;
month+=1;
if(month>12) {
month=1;
year+=1;
}
}
}
总结:一个值有两个状态,如果值是会反复变化的话,就需要if-else语句两个都要使用。
题目集5 7-4
问题:在写代码时不知道如何用List、Set或Map其中的一种接口,对List,Set,Map掌握不好,学习后写过的代码:
List<KeyWords> list = new ArrayList<>();
int r = 0;
for(int a = 0;a < key.length;a++) {
KeyWords keyWords = newKeyWords(key[a],0);
for(int z = 0;z < c.length;z++) {
if(key[a].equals(c[z])) {
keyWords.timeIncrement();
}
}
//如果关键字次数不为0,则增加到list列表中
if(keyWords.getTimes() != 0) {
list.add(keyWords);
}
}
Iterator<KeyWords> itr = list.iterator();
while(itr.hasNext()) {
KeyWords e = itr.next();
System.out.println(e.showStatus());
}
总结:List接口其实就是个动态数组,数组的长度可以改变,通过add将需要添加的东西添加进去,如果需要遍历,可以通过Iterator遍历整个list链表。
改进建议
1.这几道题的圈复杂度基本上都在10-19之间,虽然比上次低了一些,但是还是没降到10以下,下次写代码时也还需要继续关注代码的复杂度问题;
2.对复杂的正则表达式使用掌握的不好,导致题目集4 7-1得不到满分,在今后的学习中会进一步对正则表达式做更深刻的理解;
3.在今后的复杂编码中,能使用继承,多态的就使用,能使代码更加的简洁化,父类对象是所有的子类对象公共特征、行为的抽象。
4.今后的编程中,合理的运用多个类,并且一个类只包含一个引起它变化的因素,如果超过一个变化因素,想办法把它分解成多个类。
总结
Pattern和Matcher
1.Pattern.split(CharSequence input)(括号里为分割的标识)
用于分割字符串,并返回一个String[].
2.Pattern.matches(String regex,CharSequence input)
快速匹配字符串,适用于匹配一次,且匹配全部字符串
3.Pattern,Matcher
Pattern p=Pattern.compile("\d+"); (括号里为正则表达式)
Matcher m=p.matcher("22bb23"); (括号里为待匹配的字符串)
m.find();返回值为true或false
m.group();得到匹配到的字符串
StringBuilder的用法
StringBuilder sb = new StringBuilder();
1.sb.append();//括号里为字符串
将字符串连接起来
2.sb.toString();//返回与原内容相同的字符串
3.sb.setCharAt(int i,char c);//将第i个代码设置为c(简单理解为替换)
4.sb.insert(int offset, String str);//再指定为之前插入字符串
5.delete(int startIndex,int endIndex):删除起始位置(含)到结尾位置(不含)之间的字符串
4.用StringBuilder输入
以exit标识符为例结束输入(若没输入结果返回"Wrong Format")
Scanner input = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
String str = input.nextLine();
while(!str.equals("exit")) {
if(str.length() != 0) {
sb.append(str);
sb.append("\n");
}
str = input.nextLine();
}
if(sb.toString().length() == 0) {
System.out.println("Wrong Format");
}
LocalDate.of(int year, int month, int dayOfMonth) 根据参数设置日期,参数分别为年,月,日
5.LocalDate\LocalTime\LocalDateTime类
//自己设置时间,静态方法
LocalDate localdate = LocalDate.of(year,month,day);
LocalTime localtime = localTime.of(hour,day);
LocalDateTime loacalDateTime = LocalDateTime.of(localDate,localTime);
6.close的意义
在java中.close 是关闭的意思。比如session.close(); 意思就是关闭session 同时释放内存
7.字符串转换为字符数组
toCharArray() 方法将字符串转换为字符数组。
8.replace与replaceAll
replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也就是字符串);
例如:将匹配到的字符串,即双引号里面的内容用空格替代
p = Pattern.compile("\"(.*?)\"");
for( int j=0;j<i;j++) {
Matcher m = p.matcher(s);
while(m.find()) {
s=s.replace(m.group()," ");
}
2)replaceAll的参数是regex,即基于正则表达式的替换
例如:将字符串s /* */里面的内容用空替换掉
String s=sb.toString();
s=s.replaceAll("/\\*.+\\*/","");
9. arrayList的排序方法
用add将要排序的数据添加到arrayList中,再用
Collections.sort(arrayList)
对arrayList进行排序,例如:
将所有面积放在arrayList,在对其进行排序
ArrayList<Double> arrayList = new ArrayList<>();
arrayList.add(a[p].getArea());
arrayList.add(b[q].getArea());
arrayList.add(c[r].getArea());
Collections.sort(arrayList);
arrayList的长度获得:
arrayList.size()
10.to CharArray()
toCharArray() 方法将字符串转换为字符数组。
String str = in.next();
char[] c = str.toCharArray();
我觉得我还需要对继承,多态,正则表达式等做进一步的学习。
老师的教学安排的很合理,作业难度适中,上完课之后进行巩固,一段时间进行学习总结。

浙公网安备 33010602011771号