- 前言
- 现在我们的JAVA已经接近尾声了,对于编程思想和方法的改变依旧是难点,但是经过这一段时间的学习还是让我在OOP思想的理解上有了很大的进步,也学会了许多知识点,初步明白了不同语言之间的差别,不断的总结让我不停地思考自身的不足和缺陷,也让我不断的进步与努力,接下来便是对最后学习阶段的总结与认知。
1. 习题集六:
本次题目集一共包含两道题目,第一题是电信计费系统的设计,其中涉及到了正则表达式的运用,但是由于不够熟练,导致非法测试点好多无法实现,丢掉了十几分;第二题的难度更为简单一点,主要内容是定义容器Container接口,考察了对多态的测试,以及对接口的相关内容,主要难点为了接口的实现、抽象方法重写和多态机制测试,但做起来相对第一题来说容易一点。
2. 习题集七:
本次题目集一共包含了三道题目,第一题的难度在本次习题中难度最高,二,三题的难度相对而言难度一般。第一题难度较大,我得到的分很少,里面涉及到许多知识点还没有掌握,在学习过后仍然不是很明白,所以最后的分相当低,而第二题的考查范围主要是ArrayList和HashSet链表的使用,主要考察了对多个类的储存,再将其中的类进行数据对比,将重复的数据删除,考点为创建有序集合对象以及创建迭代器遍历集合。考点比较单一。第三题与第二题比较相似,考点也为考点为创建有序集合对象以及创建迭代器遍历集合。
3.习题集八
本次习题集一共有三道大题,难度相对于前两次的题目集有所降低,第三题是大致写一个动物发声模拟器,涉及到多态等问题,内容较为简单,第二题则是写一个shop类,可以用来巩固知识点,最难的还是第一题,但是相对前几次来说是简单的,经过询问多人后获得了满分。
- 习题集的得分情况:
习题集六:81分(满分100分)
习题集七:34分(满分100分)
习题集八:100分(满分100分)
- 设计与分析
下面为第一次的电信计费系统,其余均类似,故只对此进行讨论。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;
import javax.xml.crypto.Data;
public class Main{
public static void main(String[] args) throws ParseException {
Scanner in = new Scanner(System.in);
ArrayList<User> u = new ArrayList<User>();
ArrayList<CallRecord> c = new ArrayList<CallRecord>();
String test = "^u-0791[0-9]{7,9} 0$";
String text1 = "[t]-0791[0-9]{7,8}\\s" + "0[0-9]{9,11}\\s" +
"((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.(((0?[13578]|1[02])\\.(0?" +
"[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" +
"[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
"\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s" +
"((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})\\.((([13578]|1[02])\\.(" +
"[1-9]|[12][0-9]|3[01]))|(([469]|11)\\.([1-9]|[12][0-9]|30))|(2\\.([1-9]|[1][0-9]|2[0-8]))))|(((" +
"[0-9]{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
"\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])";
String s = in.nextLine();
for(;!s.equals("end");) {
if(s.charAt(0) == 'u') {
if(s.matches(test)) {
// if() {
String[] a = s.split("[- ]");
User user = new User(a[1]);
boolean falg = false;
for(User user1 : u) {
if(user1.getNumber().equals(a[1])) {
falg = true;
}
}
if(falg == false) {
u.add(user);
}
// }
}
}else if(s.charAt(0) == 't') {
if(s.matches(text1)) {
SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String[] b = s.split("[- ]");
String callnumberString = b[1];
String answernumberString =b[2];
String startTimeString = b[3] + " "+b[4];
String endTimeString = b[5] + " "+b[6];
Date st =simpleFormat.parse(startTimeString);
Date et = simpleFormat.parse(endTimeString);
CallRecord callRecord = new CallRecord(callnumberString,answernumberString);
callRecord.setStartTime(st);
callRecord.setEndTime(et);
c.add(callRecord);
}
}
s = in.nextLine();
}
for(CallRecord callRecord : c) {
String s1 = callRecord.getCallingNumber();
String s2 = callRecord.getAnswerNumber();
for(int i = 0; i < u.size(); i++){
if(u.get(i).getNumber().equals(s1)){
String num = s2.substring(0,4);
if(num.equals("0791")){
u.get(i).getUserRecords().addCallinglnCityRecords(callRecord);
}else if(num.equals("0701") || (num.compareTo("0790")>=0 && num.compareTo("0799")<=0)){
u.get(i).getUserRecords().addCallinglnProvinceRecords(callRecord);
}else{
u.get(i).getUserRecords().addCallinglnLandRecords(callRecord);
}
}
}
}
User[] u1 = u.toArray(new User[0]);
for(int i = 0; i < u1.length-1; i++){
for(int j = i+1 ; j < u1.length;j++){
User temp;
if(u1[i].getNumber().compareTo(u1[j].getNumber()) > 0){
temp = u1[i];
u1[i] = u1[j];
u1[j] = temp;
}
}
}
for(User user : u1){
System.out.printf("%s %.1f %.1f\n",user.getNumber(),user.calCost(),user.calBalance());
}
}
}
class User{
private UserRecords userRecords = new UserRecords();
private double balance = 100;
private double callcost = 0;
private ChangeMode changeMode = new LandlinePhoneCharging();
private String number;
public User(String number) {
this.number = number;
}
public double calBalance() {
balance = balance - changeMode.getMonthlyRent() - callcost;
return balance;
}
public double calCost() {
callcost = changeMode.calCost(userRecords);
return callcost;
}
public UserRecords getUserRecords() {
return userRecords;
}
public void setUserRecords(UserRecords userRecords) {
this.userRecords = userRecords;
}
public ChangeMode getChargeMode() {
return changeMode;
}
public void setChargeMode(ChangeMode changeMode) {
this.changeMode = changeMode;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
abstract class ChangeMode{
private ArrayList<ChargeRule> chargeRules = new ArrayList<>();
public ArrayList<ChargeRule> getChargeRules(){
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules = chargeRules;
}
public abstract double calCost(UserRecords userRecords) ;
public abstract double getMonthlyRent() ;
}
class LandlinePhoneCharging extends ChangeMode{
private double monthlyRent = 20;
CallChargeRule LandPhoneInCityRule = new LandPhoneInCityRule();
CallChargeRule LandPhonelnProvinceRule = new LandPhonelnProvinceRule();
CallChargeRule LandPhoneInLandRule = new LandPhoneInLandRule();
public double calCost(UserRecords userRecords) {
double cost = 0;
cost += LandPhoneInCityRule.calCost(userRecords.getCallinglnCityRecords());
cost += LandPhonelnProvinceRule.calCost(userRecords.getCallinglnProvinceRecords());
cost += LandPhoneInLandRule.calCost(userRecords.getCallinglnLandRecords());
return cost;
}
public double getMonthlyRent() {
return monthlyRent;
}
}
class UserRecords{
private ArrayList<CallRecord> callinglnCityRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> callinglnProvinceRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> callinglnLandRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> answerlnCityRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> answerlnProvinceRecords = new ArrayList<CallRecord>();
private ArrayList<CallRecord> answerlnLandceRecords = new ArrayList<CallRecord>();
private ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
private ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
public ArrayList<CallRecord> getCallinglnCityRecords(){
return callinglnCityRecords;
}
public ArrayList<CallRecord> getCallinglnProvinceRecords(){
return callinglnProvinceRecords;
}
public ArrayList<CallRecord> getCallinglnLandRecords(){
return callinglnLandRecords;
}
public ArrayList<CallRecord> getAnswerlnCityRecords(){
return answerlnCityRecords;
}
public ArrayList<CallRecord> getAnswerlnProvinceRecords(){
return answerlnProvinceRecords;
}
public ArrayList<CallRecord> getAnswerlnLandceRecords(){
return answerlnLandceRecords;
}
public ArrayList<MessageRecord> getSendMessageRecords(){
return sendMessageRecords;
}
public ArrayList<MessageRecord> getReceiveMessageRecords(){
return receiveMessageRecords;
}
public void addCallinglnCityRecords(CallRecord callRecord){
callinglnCityRecords.add(callRecord);
}
public void addCallinglnProvinceRecords(CallRecord callRecord){
callinglnProvinceRecords.add(callRecord);
}
public void addCallinglnLandRecords(CallRecord callRecord){
callinglnLandRecords.add(callRecord);
}
public void addAnswerlnCityRecords(CallRecord answerRecord){
answerlnCityRecords.add(answerRecord);
}
public void addAnswerlnProvinceRecords(CallRecord answerRecord){
answerlnProvinceRecords.add(answerRecord);
}
public void addAnswerlnLandceRecords(CallRecord answerRecord){
answerlnLandceRecords.add(answerRecord);
}
public void addSendMessageRecords(MessageRecord sendMessageRecords){
addSendMessageRecords(sendMessageRecords);
}
public void addReceiveMessageRecords(MessageRecord receiveMessageRecords){
addReceiveMessageRecords(receiveMessageRecords);
}
}
abstract class CommunicationRecord{
protected String callingNumber;
protected String answerNumber;
public String getCallingNumber() {
return callingNumber;
}
public void setCallingNumber(String callingNumber) {
this.callingNumber = callingNumber;
}
public String getAnswerNumber() {
return answerNumber;
}
public void setAnswerNumber(String answerNumber) {
this.answerNumber = answerNumber;
}
}
class CallRecord extends CommunicationRecord{
private Date startTime;
private Date endTime;
private String callingAddressAreaCode;
private String answerAddressAreaCode;
public CallRecord(String callnumberString, String answernumberString) {
// TODO Auto-generated constructor stub
setCallingNumber(callnumberString);
setAnswerNumber(answernumberString);
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getCallingAddressAreaCode() {
return callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode) {
this.callingAddressAreaCode = callingAddressAreaCode;
}
public String getAnswerAddressAreaCode() {
return answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
this.answerAddressAreaCode = answerAddressAreaCode;
}
}
class MessageRecord extends CommunicationRecord{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
abstract class ChargeRule{
public ChargeRule() {
super();
// TODO Auto-generated constructor stub
}
}
abstract class CallChargeRule extends ChargeRule{
// SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
public abstract double calCost(ArrayList<CallRecord> callRecords) ;
}
class LandPhoneInCityRule extends CallChargeRule{
int minutes;
int minute;
int s;
public double calCost(ArrayList<CallRecord> c) {
for(CallRecord callRecord : c) {
s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000);
minute = (int)(s/60.0);
if(s/60.0>minute) {
minute++;
}
minutes+=minute;
}
return minutes*0.1;
}
}
class LandPhoneInLandRule extends CallChargeRule{
int minutes;
int minute;
int s;
public double calCost(ArrayList<CallRecord> c) {
for(CallRecord callRecord : c) {
s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000);
minute = (int)(s/60.0);
if(s/60.0>minute) {
minute++;
}
minutes+=minute;
}
return minutes*0.6;
}
}
class LandPhonelnProvinceRule extends CallChargeRule{
int minutes;
int minute;
int s;
public double calCost(ArrayList<CallRecord> c) {
for(CallRecord callRecord : c) {
s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000);
minute = (int)(s/60.0);
if(s/60.0>minute) {
minute++;
}
minutes+=minute;
}
return minutes*0.3;
}
}
下面的是省内计费的部分代码,其中对时间的换算很重要,经查询学会了date类的简单运用,
Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。
class LandPhonelnProvinceRule extends CallChargeRule{
int minutes;
int minute;
int s;
public double calCost(ArrayList<CallRecord> c) {
for(CallRecord callRecord : c) {
s = (int)(callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime())/(1000);
minute = (int)(s/60.0);
if(s/60.0>minute) {
minute++;
}
minutes+=minute;
}
return minutes*0.3;
}
}
import java.awt.geom.Area;
import java.text.ParseException;
import java.util.Scanner;
import javax.swing.text.AbstractDocument.LeafElement;
//定义容器Container接口。模拟实现一个容器类层次结构,并进行接口的实现、抽象方法重写和多态机制测试。
//各容器类实现求表面积、体积的方法。
//
//定义接口Container:
//属性:
//public static final double pi=3.1415926;
//抽象方法:
//其中两个静态方法分别计算返回容器数组中所有对象的面积之和、周长之和;
//定义Cube类、Cylinder类均实现自Container接口。
//Cube类(属性:边长double类型)、Cylinder类(属性:底圆半径、高,double类型)。
public class Main{
public static void main(String[] args) throws ParseException {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
Container[] containers = new Container[n];
for(int i = 0 ; i < n ; i++) {
String a = in.next();
if(a.equals("cube")){
containers[i] = new Cube(in.nextDouble());
}else if(a.equals("cylinder")) {
containers[i] = new Cylinder(in.nextDouble(), in.nextDouble());
}
}
System.out.printf("%.2f\n%.2f",Container.sumofArea(containers),Container.sumofVolume(containers));
in.close();
}
}
interface Container{
public abstract double area();
public abstract double volume();
public static double sumofArea(Container c[]) {
double sum = 0;
for(int i = 0;i < c.length;i++) {
sum += c[i].area();
}
return sum;
}
public static double sumofVolume(Container c[]) {
double num = 0;
for (Container container : c) {
num += container.volume();
}
return num;
}
}
class Cube implements Container{
private double length;
public Cube(double length) {
this.length = length;
}
public double area() {
return length*length*6;
}
public double volume() {
return length*length*length;
}
}
class Cylinder implements Container{
private double r;
private double high;
public static final double pi=3.1415926;
public Cylinder(double r,double high) {
this.r = r;
this.high = high;
}
public double area() {
return pi*r*r*2 + 2*r*pi*high;
}
public double volume() {
return pi*r*r*high;
}
}
本题考查多态的类型,在期末考试时出现问题,PI要用Math.PI,没有用导致第一题都没有满分,除非题目有要求,否则一律使用Math.PI。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Shop myShop = new Shop();
Scanner inScanner = new Scanner(System.in);
int num = inScanner.nextInt();
if(num >= 3) {
myShop.setMilkCount(num);
myShop.innerCoupons50.buy();
System.out.println("使用了面值为50的购物券进行支付");
System.out.println("牛奶还剩"+myShop.getMilkCount() +"箱");
myShop.innerCoupons100.buy();
System.out.println("使用了面值为100的购物券进行支付");
System.out.println("牛奶还剩"+ myShop.getMilkCount() +"箱");
}
inScanner.close();
}
}
class Shop{
private int milkCount;
InnerCoupons innerCoupons50;
InnerCoupons innerCoupons100;
public void setMilkCount(int milkCount) {
this.milkCount = milkCount;
}
public int getMilkCount() {
return milkCount;
}
public Shop() {
innerCoupons50 = new InnerCoupons(50);
innerCoupons100 = new InnerCoupons(100);
}
class InnerCoupons{
int value;
public InnerCoupons(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void buy() {
milkCount -= this.value/50;
}
}
}
- 踩坑心得
①正则表达式默认进行贪婪匹配,可以用?来实现非贪婪匹配;
②字符串的直接比较可以采用equals连接前后两者,没必要依次比较每一个字符;
③Find函数用来对原始数据中某个字符串进行定位,以确定其位置,可以简化程序代码,使程序更加简洁明了;
④要善于用Java中一些功能方便的类,这样可以大大的提高我们的解题效率。
⑤在进行代码的编写时应该尽量避免代码的重复编写,使我的代码更加的简洁.
⑥不断优化实现功能的代码算法,实现对代码的凝练和升华,不断熟悉代码和知识,加快做题速度。
- 改进建议
①代码尽可能融入新的知识,一个功能一个类,避免一个类复用,导致代码的容错率降低,后期应逐步加入继承等新知识。
②顺序结构不够简洁,逻辑较为混乱,应在设计代码时提前用流程图进行规划,使程序清晰易读。
③不断考虑可能会出现的情况,不仅仅局限于测试点的通过。
④正则表达式的学习还不到位,仍然需要继续在网上查找资料来学习。
⑤在一些代码的关键节点,我应该加上一些注释,方便之后的查阅和修改。
⑥在进行继承关系描述时,需要注意格式问题,用super关键字来调用父类中的方法。
- 总结
①深入了解了正则表达式后学会了简单运用正则表达式。
②理解了面向对象程序设计封装性、继承性与多态性三大技术特性。
③理解面向过程程序设计和面向对象程序设计的区别。
④学习之路任重而道远,仍然需要努力,多向他人请教,问老师。