PTA也写过了三次作业了,虽然很遗憾都没有拿到满分,
不过在练习的过程中也很直观的学到了一点:做题不能因为不会就轻易放弃,要学会钻研。
借着这次机会,好好的和之前的自己“算个帐”。
首先是第一次作业中:
1.涉及到了对象的包装,即面向对象的程序的三大技术之一,如:
设计一个风扇类:
点击查看代码
class Fan{
``` final int SLOW = 1;
final int MEDIUM = 2;
final int FAST = 3;
private int speed = SLOW;
private boolean on = false;
private double radius = 5;//半径
private String color = "white";
public int getSpeed(){
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isOn(){
return on;
}
public void setOn(boolean on) {
this.on = on;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Fan(int fanSpeed,boolean fanOn,double fanRadius,String fanColor){
speed = fanSpeed;
on = fanOn;
radius = fanRadius;
color = fanColor;
}
public Fan(){
}
public String toString(){
if(on)
return "-------\nMy Fan\n-------\nspeed "+speed+"\ncolor "+color+"\nradius "+radius+"\nfan is on";
else
return "-------\nMy Fan\n-------\nspeed "+speed+"\ncolor "+color+"\nradius "+radius+"\nfan is off";
}
}
- 1.属性,
- 2.方法。
使得该类与其他的类之间的交互变得顺畅方便
2.解析字符串:
在第一次作业的最后一题中,我们需要对其中的数据进行提取与解析:
像这里,面对这样有规律模板的字符串,在我还没接触正则表达式时,
我选择的是用字符串切割来进行提取信息:
点击查看代码
Topic b[] = new Topic[size];//存size个题目和标准答案;
String str = "";
str = scanf.nextLine();//吸收size后的回车
String topic = "";//装题目
String answer = "";//装答案
int num=0,start = 0,start1 = 0;
int f=1;
for(int i=0;i<size;i++)
{
str = scanf.nextLine();//读取一整行
start = str.indexOf("#A");//第一个“#A”位置
start1 = str.indexOf("#Q");//#Q的位置
num = Integer.valueOf(str.substring(3,start1).trim());
//System.out.println(num);
topic = str.substring(start1+3,start);
topic = topic.trim();
answer = str.substring(start+3);
b[num-1] = new Topic(num,topic,answer);
}
利用Java.lang.String
类里的的substring
,indexOf
方法,可以方便的对字符串找到标志切割点,进行切割,提取。
不过,在后期的学习中我们又学到了正则表达式
这一利器,可以方便的分割字符串,
也在后期的尝试下,重新做对了这道题,所以说,一切恐惧都源于火力不足,在今后应该注重课外的学习,不仅仅是在意作业。
这是用正则表达式的分割方法:
点击查看代码
String restr1 = " *#N: *(\\d\\d*) *#Q: *(.*)#A: *(.*)";
String restr2 = " *#A: *([^ A#:]*)";
int num = scanf.nextInt();//题目数量
String str = scanf.nextLine();//吸收回车
Pattern pattern;
Matcher matcher;
ArrayList<Topic> topics = new ArrayList<Topic>();//题目集
ArrayList<Answer> answers = new ArrayList<Answer>();
for(int i=0;i<num;i++)
{
str = scanf.nextLine();
if(str.contains("#N"))
{
pattern = Pattern.compile(restr1);
matcher = pattern.matcher(str);
if(matcher.find())
{
topics.add(new Topic(Integer.parseInt(matcher.group(1)),matcher.group(2).trim(),matcher.group(3).trim()));
}
continue;
}
}
在第二次作业中:
1.第一题是绝对值得一讲的:
在第一题中
要求编写一个类,手机类,且要实现Comparable接口,重写compareTo方法
在前期的学习中,我们知道,在String这个类中有着一个比较字符串的方法:compareTo()
;
实际操作中,我们自己定义的类,要实现重写这个方法,首先就是要用
implements Comparable<ClassName>
语句实现Comparable接口,这样,我们所定义的类就可以有compareTo
方法,然后再对该方法进行重写:
点击查看代码
class MobilePhone implements Comparable<MobilePhone>{
private String type;
private int price;
public MobilePhone(String type,int price)
{
this.type = type;
this.price = price;
}
public int compareTo(MobilePhone other)
{
return this.price-other.price;
}
public String typeGet()
{
return type;
}
public void typeSet(String type)
{
this.type = type;
}
public int priceGet()
{
return price;
}
public void priceSet(int price)
{
this.price = price;
}
public String toString()
{
return "型号:"+type+",价格:"+price;
}
}
compareTo
返回的是int
类型的值,像这样在MobilePhone 里重写compareTo
后,就可以用于比较两个MobilePhone 对象的大小了
当然,之后也可以根据需要,使用 Collections.sort(ListName)
方法对数组或链表进行从小到大的排序;
2.对构造方法学习:
可以如图一样,一个类的构造方法可以进行重载,不过需要值得一提的是:在未显示给出构造方法的时候,系统会自动给出一个无参的构造方法,当显示给出构造方法时,则不会自动给出无参的构造方法。
在多数情况下,我们还是需要自己根据需要来自己创建构造方法,所以,对构造方法
的熟悉是很重要的。
构造方法的特点:
- 无返回类型;
- 名字必须与类名同名;
- 可以利用重载;
3.判题系统-2:
判题系统果然有一就有二;
在这次的判题系统中,相较于上次,不同的是,增加了试卷这一类,类的不断增加,对其内部的关系的理清也会变得有所复杂,
吸取上次的教训,我们知道面对这里,我们可以使用正则表达式
来对付这种有规定格式的题目。
上代码:
通过类似的正则表达式
,同样可以对其他两个数据:题目,答卷,进行数据解析。
这里学到了一个习惯,对付这样的规律模板,可以提前预写好每个正则表达式如:
前提是正则表达式
得写对,遇到最多的情况就是,对空格的匹配错误,这方面还得多写,通过多写代码提高肌肉记忆。
判题系统2,除二次加深了对正则表达式的印象外,就是加强了对对象间的关联关系的掌握
在第三次作业中:
1.初次使用了日期类:
在这里我用的本来是Calendar
日历类:
但是有个弊端让我放弃了使用calendar
的念想,就是,当输入的日期不合理时,它会自动的调成合理的,
例如:输入:2月30号,则会保存为3月1号,对日期的非法性判断起迷惑,所以后来就自己定义了一个类似于calendar
的类,
点击查看代码
class Time implements Comparable<Time>{
private int year;
private int mon;
private int day;
private int week;
public int getYear() {
return year;
}
public int getMon() {
return mon;
}
public int getDay() {
return day;
}
public int getWeek(){
return week;
}
public Time(){
}
public Time(int year, int mon, int day) {
this.year = year;
this.mon = mon;
this.day = day;
this.week = toWeek(year,mon,day)%7;
if(week==0)
week = 7;
}
public static int toWeek(int year,int mon,int day)//1940的1月1号为星期一
{
//假如year==1941 1月1日
int s = 0;
for(int i=1940;i<year;i++)
{
if(Main.isLeap(i))
s+=366;
else
s+=365;
}
s+=Main.dayOfYear(year,mon,day);
return s;
}
public int compareTo(Time other)
{
if(other.year>this.year)
return -1;
else if(other.year<this.year)
return 1;
else{
if(other.mon>this.mon)
return -1;
else if(other.mon<this.mon)
return 1;
else{
if(other.day>this.day)
return -1;
else if(other.day<this.day)
return 1;
else
return 0;
}
}
}
}
不过,calendar
日历类确实很方便,可以得到星期几,还可以得到年月日等,不过,需要注意的是,calendar
记录的是西方日期,所以DAY_OF_WEEK
返回的星期还应该-1使用,MONTH
返回的月份应该+1使用
2.针对第三次判题系统我们来讲讲:
即使最后的最后也没做出来,虽然嘴上说不在意,但其实还是想解决它的;
对于第三次作业,与前面两次相比,可谓是天壤之别:
- 1.在原有关系上,增加了两种的信息:删除和学生信息;
- 2.在原有基础上,增加了判错;
- 3.增加了答卷的可变性,答卷可以不按套路出牌,但是我们依旧得识别出;
1.第一点来说,首先就是实现正则表达式的书写:
不过对题目而言,我们应该重新定义一个属性:来表示题目是否存在:
再加个学生类Stu
2.增加了判错,这里我们防止漏判,多判,我们用到了String
自带的两个方法:spilt
,matches
直接看代码:
利用spilt
将str有规律的分割,再用matches
对其一一检查,好处是:不用过多的考虑空格以及字符串结束带来的种种困扰,可以有效的判错,因此在判错上也拿了满分。
3.虽然错了,不过通过课上讲解得知:可以利用HashMap
将输入的乱序答案和正序题目联系在一起。
再通过HashMap自带的get(key)方法将对应题号的答案找出来,再进行判错和打分。
以上就是对本次PTA前三次作业的总结。
对于今后,我也要不断的努力,但是,就当是我对自己说的,
“不要看到别人做到,自己没做到,就觉得自己不行了”,
“不要以为自己这次想破脑汁也没做到满分,就下次想多了也没用,试试,试过就算赢了,希望自己下次走出来,不要害怕当下的题目。下次可能就能做出来啦”