前言:

  最近的三次实验是对于电信计费的设计,包括座机,手机,信息。有很多的要求,包括:跨省聊天什么的。不同的情况的要价是不同的,所以我们需要对这些情况进行讨论。题目是给出了类图的,只需要进行

方法的具体解释就行。时间必须符合"yyyy.MM.dd HH:mm:ss"格式,使用SimpleDateFormat类。这是最麻烦的点,但在第三次作业中可不考虑这种。格式依旧:号码+英文空格符+总的话费+英文空格符+余额,可以合理的利用之前的方式来分割。很不错。

第五次:
第五次大作业是多边形的收尾,可以多次利用前面的来判定五边形的很多情况。

public static void choice1(ArrayList<Point> ps) {
            JudgePoint.wrongNumberOfPoints(ps, 5);
            Cross t = new Cross(ps.get(0),ps.get(1),ps.get(2),ps.get(3),ps.get(4));

            if(t.isPentagon()) {
                System.out.println("true");
            }
            else 
                System.out.println("false"); 
        }

这是第一个判定,很简单但也很基础,在第一次判定时我就出错了,但这很重要的,所以不可以小看,可利用四边形来进行判定这会非常简单,如上。

public static void choice2(ArrayList<Point> ps) {
            JudgePoint.wrongNumberOfPoints(ps, 5);
            Cross t = new Cross(ps.get(0),ps.get(1),ps.get(2),ps.get(3),ps.get(4));
            if(t.isPentagon()==false){
                System.out.println("not a pentagon");
                //System.exit(0);
            }else{
                if(t.ConvexOrConcave()==true){
                    
                    System.out.print("true " + OutFormat.doubleFormat(t.perimeter()) + " " + OutFormat.doubleFormat(t.area()));
                }else{
                    System.out.println("false");
                }
            }
        }
public static void choice3(ArrayList<Point> ps) {
            JudgePoint.wrongNumberOfPoints(ps, 7);
            if(ps.get(0).equals(ps.get(1))){
                System.out.print("points coincide");
                return;
            }
            Line l = new Line(ps.get(0),ps.get(1));
            Cross c = new Cross(ps.get(2),ps.get(3),ps.get(4),ps.get(5),ps.get(6));
            
            if(c.isPentagon()){
                
                if(l.isCoincide(c.l12)||l.isCoincide(c.l23)||l.isCoincide(c.l34)||l.isCoincide(c.l45)||l.isCoincide(c.l51)) {
                    System.out.print("The line is coincide with one of the lines");
                    return;
                }
                ps = c.getIntersections(l);
                //System.out.println(ps.get(0) + " " + ps.get(1));
                int num = ps.size();
                if (num == 2) {
                    double[] ds = c.calArea(ps.get(0), ps.get(1));
                    Arrays.sort(ds);
                    System.out.print(num + " " + OutFormat.doubleFormat(ds[0]) + " " + OutFormat.doubleFormat(ds[1]));
                } else {
                    System.out.print(num);
                }
            }else if(c.isQuadr()) {
                
                if(l.isCoincide(c.l12)||l.isCoincide(c.l23)||l.isCoincide(c.l34)||l.isCoincide(c.l45)||l.isCoincide(c.l51)) {
                    System.out.print("The line is coincide with one of the lines");
                    return;
                }
                Quadr q1 = c.quadrilateral();
                ps = q1.getIntersections(l);
                int num = ps.size();
                if (num == 2) {
                    //if(ps.get(0).equals(p1) )
                    
                    
                    
                    double[] ds = q1.calArea(ps.get(0), ps.get(1));
                    Arrays.sort(ds);
                    System.out.print(num + " " + OutFormat.doubleFormat(ds[0]) + " " + OutFormat.doubleFormat(ds[1]));
                } else {
                    System.out.print(num);
                }
            }else
                
                if(c.isTriangle()) {
                   
                    if(l.isCoincide(c.l12)||l.isCoincide(c.l23)||l.isCoincide(c.l34)||l.isCoincide(c.l45)||l.isCoincide(c.l51)) {
                        System.out.print("The line is coincide with one of the lines");
                        return;
                    }
                    Triangle t = c.triangle();
                    ps = t.getIntersections(l);
                    int num = ps.size();
                    if (num == 2) {
                        double[] ds = t.calArea(ps.get(0), ps.get(1));
                        Arrays.sort(ds);
                        System.out.print(num + " " + OutFormat.doubleFormat(ds[0]) + " " + OutFormat.doubleFormat(ds[1]));
                    }
                    else
                        System.out.print(num);
                }
                
                else {
                    System.out.print("not a pentagon");
                }
                
        }

如上两种方法也是同样的,更可以结合三角形进行判定,有之前的经验,我们可以做的更轻松些。

第六次:
从第六次作业开始,时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。这个明显时很重要的。所以我们必须对其进行更好地划分和处理才行。

String[] array = dateString.split("\\.");
        int year = Integer.valueOf(array[0]);
        int month = Integer.valueOf(array[1]);
        int day = Integer.valueOf(array[2]);

        if (month < 1 || month > 12) {
            return false;
        }
        int[] monthLengths = new int[] { 0, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (isLeapYear(year)) {
            monthLengths[2] = 29;
        } else {
            monthLengths[2] = 28;
        }
        int monthLength = monthLengths[month];
        if (day < 1 || day > monthLength) {
            return false;
        }
        return true;
    }

    /** 是否是闰年 */
    private static boolean isLeapYear(int year) {
        return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
    }


    public boolean judge(String input) {

        return false;
    }

分割出时间年月日,对其进行具体的如上的格式的判断。这确实是很重要的事情。如何将坐标分割开,这必须要找到准确的点可以利用sunstring()来进行分割(这是我目前唯一能想到的方式)但缺点很明显,无法广泛地进行利用只能用在这种少数的点上。再多出一些点就无法进行操作了。未实现第一题,第二三题也不可能得以实现。在完成实验过程中,我完全还是按照面向过程的形式进行书写的。在后续的2个题中我发现了是第一个题的升级,难度在一级一级的上升,但可以利用第一题的大部分进行数字提取,接下来就只是单纯的分类计算了。切割在下下个题的用处会变得跟大的。

第八次:

 

public class Main {
public static void main(String[] args) {
ArrayList<String> l1 = new ArrayList<String>();
ArrayList<String> l2 = new ArrayList<String>();
Test t = new Test(l1,l2);
t.testAndInput();
calculate a = new calculate(l1, l2);
a.display();
}
}

class Test{
ArrayList<String> l1 = new ArrayList<String>();//用于保留u
ArrayList<String> l2 = new ArrayList<String>();//用于保留m
public Test(ArrayList<String> l1,ArrayList<String> l2){
this.l1 = l1;
this.l2 = l2;
}
public void testAndInput(){
Scanner scan = new Scanner(System.in);
String lineWords;
while (!"end".equals(lineWords = scan.nextLine())){

if(lineWords.matches("u-1[0-9]{10} 3")) {//判断是哪个
//u-13305862264 3 ->13305862264
l1.add(lineWords.substring(2,lineWords.length()-2));//进行切割,保留后面的,取前不取后。
}
if(lineWords.matches("m-1[0-9]{10} 1[0-9]{10} [0-9a-zA-z,.\\s]{1,}") ){

l2.add(lineWords);
}
}
}
}


class calculate{

private ArrayList<String>l1 ;
private ArrayList<String> l2;
public calculate(ArrayList<String>l1 , ArrayList<String> l2) {
this.l1 = l1;
this.l2 = l2;
}
public void display() {
float fee = 0;//费用
float balance =100;//余额
int c1=0, c2=0, c3=0,total=0;//分别为三种情况
Collections.sort(l1);
for(String user:l1) {
for(String record:l2) {
total += c3;
if(user.equals(record.substring(2,13))) {//判断是否为同一个人的电话号码。
//m-18907910010 13305862264 welcome to jiangxi.--->welcome to jiangxi.
c1 = (record.length()-26)/10;//判断字数是否超过10个,超过10个字的算多次短信。
c2 = (record.length()-26)%10;
if(c2 !=0)//c2不为0,说明要另算。
c3 = c1+1;
else
c3 = c1;

if(total+c3<=3)//total+c3为短信条数。
fee += 0.1*c3;
if(total+c3>3&&total+c3<=5)
fee = (float) (0.3+0.2*(total+c3-3));
if(total+c3>5)
fee = (float) (0.7+0.3*(total+c3-5));
}

}
System.out.println(user+" "+fee+" "+(balance-fee));
//重新开始,初始化,但可只对于c3
fee = 0;
balance =100;
c3=0;
total=0;
}
}
}

对于前几次而言,最后一次的实验很简单。要求不太高,对着格式来就行。

类图:

  ChargeMode是计费方式的抽象类: chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。 getMonthlyRent()方法用于返回月租(monthlyRent)。 UserRecords是用户记录类,保存用户各种通话、短信的记录,

 市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、 市内接听电话、省内(不含市内)接听电话、省外接听电话的记录 以及发送短信、接收短信的记录。

图2中CommunicationRecord是抽象的通讯记录类: 包含callingNumber拨打号码、answerNumber接听号码两个属性。 CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。

 

calCost(ArrayList callRecords)方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。
SendMessageRule是发送短信的计费规则类,用于计算发送短信的费用。
LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。

心得体会:
  1.在这几次实验中,我感绝学到的更多了,包括类与类之间的关系,合理运用抽象类是真的方便啊。但多态还是挺迷的,我还是有点不知道有多大的用处,在实验中,我不知道该合理的使用在哪些位置,或者是在哪合理的使用。

 2.但对于类之间的关系我明显也没有看明白太多,感觉理解起来还是有点困难的。不论如何进行处理,都还是更加偏向于自己的想法,无法完全理解类的想法,更偏向于过程。

 3.在完成最后一次作业时,知道更简单的方式,放弃了上两次的代码,这确实很不面向过程。就是有耍点小聪明在里面罢了。

 4,在这次实验中,我更加凸出了思维,在写下这些代码时,我不时地添加注释使我保持更清晰的代码思路,确实还是很有帮助的。