哈哈的第三次BLOG作业

(1)前言:后三次大作业主要是电信计费系列题目,题目说简单也不简单,说难也难。然后第六次大作业除电信计费的题目外还有一个多态测试的题,这个较简单。第七次大作业共有三题,第一题为电信计费系列题,第二第三题难度适中。第八次大作业第一题也为电信计费系列,但是相较于前两次,这次较简单,第二第三题也比较简单。详情见下文。

(2)设计与分析:因为电信计费系列是一次一次增加新功能的所以我就附上一份源代码,但是写的不是很好。

题目为:

7-1 电信计费系列2-手机+座机计费
 
作者 蔡轲
单位 南昌航空大学

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3 10:05:11

输入:
输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,含手机和座机用户
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题在电信计费系列1基础上增加类型1-手机实时计费。
手机设置0或者座机设置成1,此种错误可不做判断。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
输入格式增加手机接打电话以及收发短信的格式,手机接打电话的信息除了号码之外需要额外记录拨打/接听的地点的区号,比如:
座机打手机:
t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:
t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11

注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。

输出:
根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条通讯、短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。
 

建议类图:
参见图1、2、3:

image.png
图1

图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。
UserRecords是用户记录类,保存用户各种通话、短信的记录,    
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
 

image.png

图2

图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
 

image.png
图3

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

(提示:可以从UserRecords类中获取各种类型的callRecords)。
注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:

在这里给出一组输入。例如:

u-13811111111 1
t-13811111111 0791 13811111110 020 2022.1.3 08:00:00 2022.1.3 08:09:20
end
 

输出样例:

在这里给出相应的输出。例如:

13811111111 3.0 82.0
这里是实际类图

 

 


下面为源码,点击加号展开
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.ArrayList;

public class Main {
    static int m = 0;
     static User[] user = new User[2];
     static CallRecord[] callRecord = new CallRecord[2];

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in  = new Scanner(System.in);
        String s1 ;
        
                while(true) {
                     s1 = in.nextLine();
                     if(!s1.equals("end")) {
                        if(s1.charAt(0)=='u') {
                            String[] str = s1.split(" ");
                            if(isLegal_1(s1)) {
                                String n = str[0].substring(2,str[0].length());
                                switch(Integer.parseInt(str[1])) { 
                                case 0:
                                    LandLinePhoneCharging landLinePhoneCharging = new LandLinePhoneCharging();
                                    user[m] = new User(landLinePhoneCharging,n);
                                    m++;
                                    break;
                                case 1:
                                    MobileLinePhoneCharing mobileLinePhoneCharing = new MobileLinePhoneCharing();
                                    user[m] = new User(mobileLinePhoneCharing,n);
                                    m++;
                                    break;
                                }
                            }
                        } 
                        if(s1.charAt(0)=='t') {
                            if(isLegal_2(s1)) {
                                String[] str = s1.split(" ");
                                String s = str[0].substring(2,str[0].length());
                                int n = getUser(s);
                                int a = getCallDuration(str[5],str[7]);
                                CallRecord callRecord = new CallRecord(str[5],str[7],a,str[1],str[3]);
                                user[n].getUsersRecords().addCallingInLandRecords(callRecord);
                            }
                        }
                     }
                    
                    else
                        break;
                }
                for(int i =0;i<m;i++) {
                        
                    System.out.print(user[i].number+" "+String.format("%.1f", user[i].calCost())+" "+String.format("%.1f", user[i].calBalance()));
                    }

                
                            
    }
    
    
    //判断输入是否合法
    public static boolean isLegal_1(String str) {
        if(str.charAt(0)=='u'&&str.charAt(1)=='-') {
            String[] s = str.split(" ");
            if(s[0].length()==14||s[0].length()==13) {
                
//                 int a= Integer.parseInt(str.substring(3, 6));//获取区号后三位
//                 if(str.charAt(2)=='0'&&((a>=790&&a<=799)||a==701)) {
//                     return true;
//                 }
//                 else
//                     return false;
                
                return true;
            }
            else
                return false;
        }
        else
            return false;
    }
    public static boolean isLegal_2(String str) {
        if(str.charAt(0)=='u'&&str.charAt(1)=='-') {
            String[] s = str.split(" ");
            if(s[0].length()==14||s[0].length()==13&&(s[1].length()==12||s[1].length()==11)) {
                return true;
            }
            else
                return true;
        }
        else
            return true;
        
    }
    
    
    //判断省内,省外,市内电话
    public static int Area(String s1,String[] s) {
        int a = 0;
         int b= Integer.parseInt(s1.substring(1, 4));//获取区号后三位
         int c= Integer.parseInt(s[1].substring(1, 4));//获取区号后三位
         if((b>=790&&b<=799||b==701)&&(c>=790&&c<=799||c==701)) {
             if(b==791&&c==791) {
                 a=1;//市内
             }
             else
                 a=2;//省内
         }
         else
             a=3;//省外
        return a;
    }
    
    
    //根据号码找到对应的用户
    public static int getUser(String s) {
        int n = 0;
        for(int i = 0;i<m;i++) {
            if(s.equals(user[i].number)) {
                n=i;
            }
        }
        return n;
    }
    
    //计算通话时长
    public static int getCallDuration(String s1,String s2) {
        String a[] = s1.split(":");
        String b[] = s2.split(":");
        int sum = 0;
        int hour = 0;
        int minute = 0;
        int miao = 0;
        hour = Integer.parseInt(a[0])-Integer.parseInt(b[0]);
        
        minute =  Integer.parseInt(b[1]) - Integer.parseInt(a[1]);
        if(Integer.parseInt(b[2]) - Integer.parseInt(a[2])>0) {
            miao = 1;
        }
        else
            miao = 0;
        sum = 60*hour+minute+miao;
        return sum;
    }
}
 abstract class MessageChargeRule extends ChargeRule {
    public double calCost(ArrayList<MessageRecord> messageRecords) {
        return 0;
    }
}


 class MessageRecord extends CommunicationRecord {
    private String message;
    public String getMessage() {
        return this.message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    
}
 class MobileLinePhoneCharing extends ChargeMode {
    private double monthlyRent = 15;
    double calCallInCity= 0;
    double calCallInPronvince = 0;
    double calCallInLand = 0;
    double calAnswerInLand = 0;

    @Override
    public double calCost(UserRecords userRecords) {
        // TODO Auto-generated method stub
    for(int i = 0;i<userRecords.getCallingInCityRecords().size();i++) {
                 
            calCallInCity  =calCallInCity+ userRecords.getCallingInCityRecords().get(i).getCallDuration()*0.1;
    }
    for(int i =0;i<userRecords.getCallingInPronvinceRecords().size();i++) {
        
            calCallInPronvince = calCallInPronvince + userRecords.getCallingInPronvinceRecords().get(i).getCallDuration()*0.2;
    }
    for(int i =0;i<userRecords.getCallingInLandRecords().size();i++) {
    
            calCallInLand = calCallInLand + userRecords.getCallingInLandRecords().get(0).getCallDuration()*0.3;
    }
    for(int i = 0;i<userRecords.getAnswerInLandReords().size();i++) {
            calAnswerInLand = calAnswerInLand + userRecords.getAnswerInLandReords().get(i).getCallDuration()*0.3;
    }
    double result = calCallInCity + calCallInPronvince + calCallInLand + calAnswerInLand;
    return result;
    }

    @Override
    public double getMonthlyRent() {
        // TODO Auto-generated method stub
        return this.monthlyRent;
    }

}

 class SendMessageRule extends MessageChargeRule {
    public double calCost(ArrayList<MessageRecord> messageRecords) {
        return 0;
        
    }
}

 class User {
    UserRecords userRecords = new UserRecords();
    double balance = 100;
    ChargeMode chargeMode;
    public User(ChargeMode chargeMode, String number) {
        super();
        this.chargeMode = chargeMode;
        this.number = number;
    }
    String number;
    public double calBalance() {
        //double a = this.chargeMode.calCost(getUsersRecords());
        this.balance = this.balance - (-this.calCost()+this.calCost()) -this.chargeMode.getMonthlyRent();
        return balance;
    }
    public double calCost() {
        double result = this.chargeMode.calCost(getUsersRecords());
        return result;
    }
    public UserRecords getUsersRecords() {
        return userRecords;
    }
    public void setUserRecords(UserRecords userRecords) {
        this.userRecords = userRecords;
    }
    public double getBalance() {
        return balance;
    }
    public ChargeMode getChargeMode() {
        return chargeMode;
    }
    public void setChargeMode(ChargeMode chargeMode) {
        this.chargeMode = chargeMode;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public User( String number) {
        super();
        
        this.number = number;
    }
    
}
 class UserRecords {
    ArrayList<CallRecord> callingInCityRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> callingInPronvinceRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> callingInLandRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> answerInCityRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> answerInPronvinceRecords = new ArrayList<CallRecord>();
    ArrayList<CallRecord> answerInLandRecords = new ArrayList<CallRecord>();
    ArrayList<MessageRecord> sendMessageRecords = new ArrayList<MessageRecord>();
    ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<MessageRecord>();
    public void addCallingInCityRecords(CallRecord callRecord) {
        callingInCityRecords.add(callRecord);
    }
    public void addCallingInPronvinceRecords(CallRecord callRecord) {
        callingInPronvinceRecords.add(callRecord);
    }
    public void addCallingInLandRecords(CallRecord callRecord) {
        callingInLandRecords.add(callRecord);
    }
    public void addAnswerInCityRecords(CallRecord callRecord) {
        answerInCityRecords.add(callRecord);
        
    }
    public void addAnswerInPonrvinceRecords(CallRecord callRecord) {
        answerInPronvinceRecords.add(callRecord);

    }
    public void addAnswerInLandRecords(CallRecord callRecord) {
        answerInLandRecords.add(callRecord);

    }
    public ArrayList<CallRecord> getCallingInCityRecords() {
        return callingInCityRecords;
    }
    public ArrayList<CallRecord> getCallingInPronvinceRecords() {
        return callingInPronvinceRecords;
    }
    public ArrayList<CallRecord> getCallingInLandRecords() {
        return callingInLandRecords;
    }
    public ArrayList<CallRecord> getAnswerInCityRecords() {
        return answerInCityRecords;
    }
    public ArrayList<CallRecord> getAnswerInPronvinceRecords() {
        return answerInPronvinceRecords;
    }
    public ArrayList<CallRecord> getAnswerInLandReords() {
        return answerInLandRecords;
    }
    public void addSendMessageRecords(MessageRecord sendMessageRecord) {
        sendMessageRecords.add(sendMessageRecord);
    }
    public void addReceiveMessageRecords(MessageRecord receiveMessageRecord) {
        receiveMessageRecords.add(receiveMessageRecord);
    }
    public ArrayList<MessageRecord> getSendMessageRecords(){
        return this.sendMessageRecords;
    }
    public ArrayList<MessageRecord> getReceiveMessageRecords(){
        return this.receiveMessageRecords;
    }
    
}
 class LandPhoneInPronvinceRule extends CallChargeRule {
    public double calCost(ArrayList<CallRecord> callrecords) {
            return 0;
        }    
}
 class LandPhoneInLandRule extends CallChargeRule {
    public double calCost(ArrayList<CallRecord> callrecords) {
        return 0;
    }    
}
 class LandPhoneInCityRule extends CallChargeRule {
    public double calCost(ArrayList<CallRecord> callrecords) {
        
        return 0;
    }
}


 class LandLinePhoneCharging extends ChargeMode {
    private double monthlyRent = 20;
    double calCallInCity= 0;
    double calCallInPronvince = 0;
    double calCallInLand = 0;
    @Override
    public double calCost(UserRecords userRecords) {
        for(int i = 0;i<userRecords.getCallingInCityRecords().size();i++) {
         
                    calCallInCity  =calCallInCity+ userRecords.getCallingInCityRecords().get(i).getCallDuration()*0.1;
        }
        for(int i =0;i<userRecords.getCallingInPronvinceRecords().size();i++) {
            
                    calCallInPronvince = calCallInPronvince + userRecords.getCallingInPronvinceRecords().get(i).getCallDuration()*0.3;
        }
        for(int i =0;i<userRecords.getCallingInLandRecords().size();i++) {
        
                calCallInLand = calCallInLand + userRecords.getCallingInLandRecords().get(0).getCallDuration()*0.6;
        }
        double result = calCallInCity + calCallInPronvince + calCallInLand;
        return result;
    }
    
    @Override
    public double getMonthlyRent() {
        return this.monthlyRent;
    }
}
abstract class CommunicationRecord {
    private String callingNumber;
    private String answerNumber;
    public String getCallingNumber() {
        return this.callingNumber; 
    }
    public void setCallingNumber(String callingNumber) {
        this.callingNumber = callingNumber;
    }
    public String getAnswerNumber() {
        return this.answerNumber; 
    }
    public void setAnswerNumber(String answerNumber) {
        this.answerNumber = answerNumber;
    }
}

 abstract class ChargeRule {
        
    
}
 abstract class ChargeMode {
    ArrayList<ChargeRule>chargeRules = new ArrayList<ChargeRule>();
    public ArrayList<ChargeRule> getChargeRule(){
        return chargeRules;
    }
    public void setChargeRule(ArrayList<ChargeRule> chargeRules) {
        this.chargeRules = chargeRules;
    }
    public abstract double calCost(UserRecords userRecords);
    public abstract double getMonthlyRent() ;
    
    

}

 class CallRecord extends CommunicationRecord {
    private String startTime = new String();
    private String endTime = new String();
    public CallRecord(String startTime, String endTime, int callDuration, String callingAddressAreaCode,
            String answerAddressAreaCode) {
        super();
        this.startTime = startTime;
        this.endTime = endTime;
        this.callDuration = callDuration;
        this.callingAddressAreaCode = callingAddressAreaCode;
        this.answerAddressAreaCode = answerAddressAreaCode;
    }
    private int callDuration;//通话时长
    private String callingAddressAreaCode;
    private String answerAddressAreaCode;
    public int getCallDuration(){
        return this.callDuration;
    }
        public String getStartTime(){
        return this.startTime;
    }
    public  void setStartTime(String startTime){
        this.startTime = startTime;
    }
    public String getEndTime(){
        return this.endTime;
    }
    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }
    public String getCallingAddressAreaCode() {
        return this.callingAddressAreaCode;
    }
    public void setCallingAddressAreaCode(String callingAddressAreaCode) {
        this.callingAddressAreaCode = callingAddressAreaCode;
    }
    public String getAnswerAddressAreaCode() {
        return this.answerAddressAreaCode;
    }
    public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
        this.answerAddressAreaCode = answerAddressAreaCode;
    }
    
}
 abstract class CallChargeRule extends ChargeRule {

    
    public double calCost(ArrayList<CallRecord> callRecords) {
        
        return 0;
    }

}
View Code

第七次大作业的·第二题

经过不懈的努力,C~K终于当上了班主任。

现在他要统计班里学生的名单,但是C~K在教务系统中导出班级名单时出了问题,发现会有同学的信息重复,现在他想把重复的同学信息删掉,只保留一个,
但是工作量太大了,所以找到了会编程的你,你能帮他解决这个问题吗?

输入格式:

第一行输入一个N,代表C~K导出的名单共有N行(N<100000).

接下来的N行,每一行包括一个同学的信息,学号 姓名 年龄 性别。

输出格式:

第一行输出一个n,代表删除重复名字后C~K的班级共有几人。

接下来的n行,输出每一个同学的信息,输出按照学号从小到大的顺序。

输入样例:

6
0001 MeiK 20 M
0001 MeiK 20 M
0002 sdk2 21 M
0002 sdk2 21 M
0002 sdk2 21 M
0000 blf2 22 F
 

输出样例:

3
0000 blf2 22 F
0001 MeiK 20 M
0002 sdk2 21 M
类图比较简单

 

 


附上源码,点击加号展开
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String ss = in.nextLine();
        Message message = new Message();
        for(int i = 0;i<n;i++) {
            String str = in.nextLine();
            String[] s = str.split(" ");
            Student student = new Student(s[0],s[1],Integer.parseInt(s[2]),s[3]);
            message.add(student);
        }
        Message message1 = removeSameInformation(message);
        System.out.println(message1.getSize());
        for(int i = 0;i<message1.getSize();i++) {
            System.out.println(message1.getMessage().get(i).number+" "+message1.getMessage().get(i).name
                    +" "+message1.getMessage().get(i).age+" "+message1.getMessage().get(i).sex);
        }
        

    }
    
    
    //寻找相同信息并保留一个并按学号排序
    public static Message removeSameInformation(Message message) {
        for(int k = 0;k<message.getSize();k++) {
            for(int i = 0;i<message.getSize()-1;i++) {
                for(int j = i+1;j<message.getSize();j++) {
                    if(message.getMessage().get(i).number.equals(message.getMessage().get(j).number)) {
                        message.remove(i);
                    }
                }
            }
        }
    for(int i = 0;i<message.getSize();i++) {
            for(int j = i+1;j<message.getSize();j++) {
                if(Integer.parseInt(message.getMessage().get(i).number)>Integer.parseInt(message.getMessage().get(j).number)) {
                    Student temp = message.getMessage().get(i);
                    Student temp1 = message.getMessage().get(j);
                    message.getMessage().set(i,temp1);
                    message.getMessage().set(j, temp);
                }
            }
        }
        
        return message;
    }
    
    
}
class Message{
    private ArrayList<Student> a = new ArrayList<Student>();
    public void add(Student student) {
        a.add(student);
    }
    public void remove (int index) {
        a.remove(index);
    }
    public ArrayList<Student> getMessage(){
        return this.a;
    }
    public int getSize() {
        return a.size();
    }
    
}    
class Student{
    String number;
    String name;
    int age;
    public Student(String number, String name, int age, String sex) {
        super();
        this.number = number;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    String sex;
    
}
View Code

第八次大作业电信计费系列之短信计费

实现一个简单的电信计费程序,针对手机的短信采用如下计费方式:
1、接收短信免费,发送短信0.1元/条,超过3条0.2元/条,超过5条0.3元/条。
2、如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。

输入:
输入信息包括两种类型
1、逐行输入南昌市手机用户开户的信息,每行一个用户。
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐 3-手机短信计费)
例如:u-13305862264 3
座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。
手机号码由11位数字构成,最高位是1。
本题只针对类型3-手机短信计费。
2、逐行输入本月某些用户的短信信息,短信的格式:
m-主叫号码,接收号码,短信内容 (短信内容只能由数字、字母、空格、英文逗号、英文句号组成)
m-18907910010 13305862264 welcome to jiangxi.
m-13305862264 18907910010 thank you.

注意:以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
输出:
根据输入的详细短信信息,计算所有已开户的用户的当月短信费用(精确到小数点后2位,单位元)。假设每个用户初始余额是100元。
每条短信信息均单独计费后累加,不是将所有信息累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。
错误处理:
输入数据中出现的不符合格式要求的行一律忽略。
本题只做格式的错误判断,无需做内容上不合理的判断,比如同一个电话两条通讯记录的时间有重合、开户号码非南昌市的号码、自己给自己打电话等,此类情况都当成正确的输入计算。但时间的输入必须符合要求,比如不能输入2022.13.61 28:72:65。

本题只考虑短信计费,不考虑通信费用以及月租费。

建议类图:
参见图1、2、3:

image.png

图1

图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。
ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。    
UserRecords是用户记录类,保存用户各种通话、短信的记录,    
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
 

image.png

图2

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

image.png

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

(提示:可以从UserRecords类中获取各种类型的callRecords)。
 

注意:以上图中所定义的类不是限定要求,根据实际需要自行补充或修改。

输入样例:

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaaaaaaaaaaaaa
end
 

输出样例:

在这里给出相应的输出。例如:

18907910010 0.3 99.7
 
### 输入样例1:
 

在这里给出一组输入。例如:

u-18907910010 3
m-18907910010 13305862264 aaaaaaaaaaaa
m-18907910010 13305862264 aaaaaaa.
m-18907910010 13305862264 bb,bbbb
end
 

输出样例1:

在这里给出相应的输出。例如:

18907910010 0.5 99.5
这个短信计费我单独分开写的,类图就会比较简单
 

 

 

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class Main {

    public static ArrayList<User> users = new ArrayList<User>();
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
//        String ss = in.nextLine();
        while(true) {
            String str = in.nextLine();
            if(!str.equals("end")) {
                
                if(str.matches("[u]-1[0-9]{10}\\s[3]")) {
                    String[] s = str.split(" ");
                    
                    User user = new User(s[0].substring(2,s[0].length()));
                    users.add(user);
                }
                else if(str.matches("[m]-1[0-9]{10}\\s"+"1[0-9]{10}\\s"+"[a-zA-Z-z0-9-,\\.\\ ]+$"
)){
                    String[] s = str.split(" ",3);
                    users.get(getUser(s[0].substring(2,s[0].length()))).messageRecord.add(s[2]);
                }
            }
            else
                break;
        }
        Collections.sort(users, new Comparator<User>() {
            
                 public int compare(User user1, User user2) {
        
                   return user1.getNumber().compareTo(user2.getNumber());
            
                       }
            
                 });
        for(int i = 0;i<users.size();i++) {
            System.out.println(users.get(i).getNumber()+" "+String.format("%.1f", users.get(i).getCalCost())+" "+String.format("%.1f", users.get(i).getCalBalance()));
        }
    }
    
    //根据号码找到对应的用户
        public static int getUser(String s) {
            int n = 0;
            for(int i = 0;i<users.size();i++) {
                if(s.equals(users.get(i).getNumber())) {
                    n=i;
                }
            }
            return n;

}
}
class User{
    private String number;
    private double balance = 100;
    private double calBalance;
    private double calCost = 0;
    ArrayList<String> messageRecord = new ArrayList<String>();
    public String getNumber() {
        return this.number;
    }
    


    public User(String number) {
        super();
        this.number = number;
    }


    //计算用了多少话费
    public double getCalCost() {
        int n = 0;
        for(int i = 0;i<this.messageRecord.size();i++){
            
            if(Count(messageRecord.get(i))+n<=3) {
                
                this.calCost = this.calCost + 0.1*Count(messageRecord.get(i));
                n = n + Count(messageRecord.get(i));
                
            }
            else if(Count(messageRecord.get(i))+n>3&&Count(messageRecord.get(i))+n<=5) {
                if(n == 0) {
                    this.calCost = this.calCost + 0.1*3 + (Count(messageRecord.get(i))-3)*0.2;
                }
                else if(n==1) {
                    this.calCost = this.calCost + 0.1*2 + (Count(messageRecord.get(i))-2)*0.2;
                }
                else if(n==2) {
                    this.calCost = this.calCost + 0.1*1 + (Count(messageRecord.get(i))-1)*0.2;
                }
                else if(n>=3) {
                    this.calCost = this.calCost  + Count(messageRecord.get(i))*0.2;
                }
                n = n + Count(messageRecord.get(i));
            }
            else if(Count(messageRecord.get(i))+n>5) {
                if(n<=3)
                    this.calCost = this.calCost + (3-n)*0.1+2*0.2+(Count(messageRecord.get(i))-5+n)*0.3;
                else if(n==4) {
                    this.calCost = this.calCost +0.2+(Count(messageRecord.get(i))-1)*0.3;
                }
                else if(n>=5) {
                    this.calCost = this.calCost + Count(messageRecord.get(i))*0.3;
                }
                    
                n = n + Count(messageRecord.get(i));
            }
                
        }
        return this.calCost;
    }
    
    
    public double getCalBalance(){
        this.calBalance = this.balance - this.calCost;
        return this.calBalance;
    }
    
    
    
    
    //计算一次话费条数
    public int Count(String string) {
        int n = 0;
        if(string.length()%10==0) {
            n = string.length()/10;
        }
        else
            n = string.length()/10 + 1;
        return n;
    }
}
View Code

第八次大作业的第二题

7-2 编写一个类Shop(商店)、内部类InnerCoupons(内部购物券)
分数 30
作者 吴光生
单位 新余学院

编写一个类Shop(商店),该类中有一个成员内部类InnerCoupons(内部购物券),可以用于购买该商店的牛奶(假设每箱牛奶售价为50元)。要求如下:
(1)Shop类中有私有属性milkCount(牛奶的箱数,int类型)、公有的成员方法setMilkCount( )getMilkCount( )分别用于设置和获取牛奶的箱数。
(2)成员内部类InnerCoupons,有公有属性value(面值,int类型),一个带参数的构造方法可以设定购物券的面值value,一个公有的成员方法buy( )要求输出使用了面值为多少的购物券进行支付,同时使商店牛奶的箱数减少value/50。
(3)Shop类中还有成员变量coupons50(面值为50元的内部购物券,类型为InnerCoupons)、coupons100(面值为100元的内部购物券,类型为InnerCoupons)。
(4)在Shop类的构造方法中,调用内部类InnerCoupons的带参数的构造方法分别创建上面的购物券coupons50、coupons100。


在测试类Main中,创建一个Shop类的对象myshop,从键盘输入一个整数(大于或等于3),将其设置为牛奶的箱数。假定有顾客分别使用了该商店面值为50的购物券、面值为100的购物券各消费一次,分别输出消费后商店剩下的牛奶箱数。

输入格式:

输入一个大于或等于3的整数。

输出格式:

使用了面值为50的购物券进行支付
牛奶还剩XX箱
使用了面值为100的购物券进行支付
牛奶还剩XX箱

输入样例:

在这里给出一组输入。例如:

5
 

输出样例:

在这里给出相应的输出。例如:

使用了面值为50的购物券进行支付
牛奶还剩4箱
使用了面值为100的购物券进行支付
牛奶还剩2箱

代码如下
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Shop myshop = new Shop();
        Scanner in = new Scanner(System.in);
        myshop.setMilkCount(in.nextInt());
        myshop.new InnerCoupons(50).buy();
        myshop.new InnerCoupons(100).buy();
        
    }

}

 class Shop {
    private int milkCount;
    InnerCoupons coupon50;
    InnerCoupons coupon100;
    
    public Shop() {
        super();
      this.coupon50 = new InnerCoupons(50);
      this.coupon100 = new InnerCoupons(100);
    }
    public void setMilkCount(int milkCount) {
        this.milkCount = milkCount;
    }
    public int getMilkCount() {
        return this.milkCount;
    }
    
    
    class InnerCoupons{
        public int value;

        public InnerCoupons(int value) {
            super();
            this.value = value;
        }
        public InnerCoupons() {
            // TODO Auto-generated constructor stub
        }
        public void buy() {
            System.out.println("使用了面值为"+this.value+"的购物券进行支付");
            System.out.println("牛奶还剩"+(getMilkCount()-value/50)+"箱");
            setMilkCount(getMilkCount()-value/50);
        }
    }
}
View Code

(3)采坑心得:要学会使用eclipse自带的类的功能,要不然自己写不仅效率低而且准确率也低,比如第七次大作业第二题要给学生信息按学号进行排序还要删除重复的信息,本来用HashSet很快就能解决,而我还用冒泡排序来排序。效率低,代码长。

(4)改进建议:一定要学会使用正则表达式,不然很多测试点过不了

(5)总结:学习情况一般,比之前好很多,可能是临近期末的原因。总的来说还是差点意思,应该更加努力,希望下学期会更好!

posted @ 2022-06-07 17:36  21201615-李俊  阅读(117)  评论(0)    收藏  举报