首页 > 其他分享 >PTA-电信计费

PTA-电信计费

时间:2022-12-09 20:34:40浏览次数:55  
标签:return String double ArrayList PTA 计费 电信 public

目录

一、前言

1.难度分析

此次博客围绕6-8次PTA题目集(电信计费),难度在电信计费的三道题目上,主要是内容太多了,让人摸不着头脑,题目其实并不难(相较于前面那几道多边形的题目),除此之外其他的几道送分题也会稍有提到注意点。

2.题量分析

比前几次大作业要少,除了送分题就三道电信计费。

3.知识点

6-7-1 电信计费系列1-座机计费

1、月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/ 分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。

2、南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701

3、座机号码由区号和电话号码拼接而成,电话号码包含7-8位数字,区号最高位是0。座机号码有以下两种类型:

(1)区号:4位 电话号码:8位
(2)区号:3位 电话号码:7位

4、时间必须符合"yyyy.MM.dd HH:mm:ss"格式(如2022.1.3 10:00:25),建议使用SimpleDateFormat类编写代码。

5、每个用户初始余额是100元。计算所有已开户的用户的当月费用(精确到小数点后2位,单位元),没有开户的用户不能计算费用。

6、注意,题目提到不检查“开户号码非南昌市的号码”这种情况,也就是说用不是南昌的座机区号开通用户也是正确的(至少在这里)。除了存在4位的座机区号外,还有3位的座机区号(如北上广),区分是3位的号码长度是10位,也就是上面知识点3中的类型(2)。

7-7-1 电信计费系列2-手机+座机计费

除了座机计费的知识点或者说内容点以外,增加了“手机计费”的以下几点:

1、月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟

个人理解:每个月要交15元月租,只有在省外接别人的电话才需要计费,市内和省内打电话都是0.3元/分钟,在省外打电话是0.6元/分钟。

2、被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:
u-13307912264 1
t-079186330022 13307912264 020 2022.1.3 10:00:25 2022.1.3
10:05:11

个人理解:看代码说话,第一行代码表示在南昌(题目默认)开通手机用户13307912264,第二行代码表示手机用户(13307912264)在区号为020(广州)接听了来自南昌的座机(079186330022)的来电。在这种情景下南昌的座机(079186330022)要以省外拨打电话为计费标准,而手机用户(13307912264)就要以省外接听电话为计费标准,虽然手机用户是在南昌开通的,但是他漫游到了广州,对于南昌来说就是省外

3、手机号码由11位数字构成,最高位是1

8--1 电信计费系列3-短信计费

1、计费方式:接收短信免费,发送短信0.1元/条超过3条0.2元/条超过5条0.3元/条。如果一次发送短信的字符数量超过10个,按每10个字符一条短信进行计算。

个人理解:结合下面的计费代码来看,先计算有多少条短信,然后根据短信的条数计费。

double sumCost = 0;//计费总金额
int number = 0;//短信条数
//遍历所有的发送记录
for (MessageRecord m : userRecords.getSendMessageRecords()) {
    //单条短信的字符数量
    int length = m.getMessage().length();
    if (length <= 10) {//字符不超过10个
        number++;//算作一条
    } else {//字符超过10个
        number += length / 10;//先取十位数相加
        if (length % 10 != 0) {//再看个位数,不为0加1
            number++;
        }
    }
}
//按总的短信条数计费
if (number <= 3) {//0-3条0.1元/条
    sumCost = number * 0.1;
} else if (number <= 5) {//3-5条0.2元/条
    sumCost = 0.3 + 0.2 * (number - 3);
} else {//超过5条0.3元/条
    sumCost = 0.7 + 0.3 * (number - 5);
}
return sumCost;

二、设计与分析

第6次大作业

6-7-1 电信计费系列 1-座机计费

源码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Scanner;
import java.util.Date;
public class Main {
    public static void main(String args[]){
        Scanner input=new Scanner(System.in);
        String s=input.nextLine();
        ArrayList<User> users = new ArrayList<>();
        inputDeal inputdeal=new inputDeal();
        boolean flag;
        while (!s.equals("end")){
            if (1 == inputdeal.judge(s)) {
                inputdeal.writeUser(users, s);
            } else if (2 == inputdeal.judge(s)) {
                inputdeal.writeRecord(users, s);
            }
            s=input.nextLine();
        }
        for(int i=0;i< users.size();i++){//冒泡排序
            for(int j=0;j< users.size()-i-1;j++){
                if(Double.parseDouble(users.get(j).getNumber()) > Double.parseDouble(users.get(j+1).getNumber())){
                    User tempu=users.get(j);
                    users.set(j,users.get(j+1));
                    users.set(j+1,tempu);
                }
            }
        }
        //System.out.println(users.size());
        for(User u:users){
            System.out.println(u.getNumber()+" "+Common.round(u.calCost(),2)+" "+Common.round(u.calBalance(),2));
        }
    }
}
class inputDeal{
    public int judge(String s){
        String []s1=s.split(" ");
        if(s1.length==2&&(s.matches("[u]-[0][7]([9][0-9]|[0][1])[0-9]{7,8} [0-3]")|| s.matches("[u]-1[0-9]{10}\\s[1]")))
            return 1;//开通用户
        if(s1.length==6&&s.matches("^t\\-0\\d{9,11}\\s0\\d{9,11}((\\s\\d{4}\\.([1-9]|([1]{1}[0-2]{1}))\\.([1-9]|"
                + "([1-2]{1}[0-9]{1})|3[0-1])\\s(([0-1][0-9])|(2[0-3]))\\:([0-5][0-9])\\:([0-5][0-9])){2})")){
            //System.out.print("a");
            return 2;//通话记录
        }
        return 0;
    }
    public void writeUser(ArrayList<User> users, String s){
        String []s1=s.split(" ");
        String number=s1[0].substring(2);
        boolean flag=false;
        User newuser = new User();
        for(User u:users){
            if(u.getNumber().equals(number))
                flag=true;//号码已经开过户
        }
        if(!flag){//没开过户的才登记
            newuser.setNumber(number);
            int mode=Integer.parseInt(s1[1]);
            if(mode==0){//收费模式0:座机
                newuser.setChargeMode(new LandlinePhoneCharging());
            }
            users.add(newuser);
        }
    }
    public void writeRecord(ArrayList<User> users, String s){
        String []s1=s.split(" ");
        s1[0]=s1[0].replace("t-","");//将t-去掉

        //初始化callRecord
        CallRecord callRecord=new CallRecord(s1);
        SimpleDateFormat format=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        Date startTime,endTime;
        try {
            startTime = format.parse(s1[2]+" "+s1[3]);
            endTime = format.parse(s1[4]+" "+s1[5]);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        callRecord.setCallingAddressAreaCode(s1[0].substring(0,4));
        callRecord.setAnswerAddressAreaCode(s1[1].substring(0,4));
        callRecord.setStartTime(startTime);
        callRecord.setEndTime(endTime);
        callRecord.setCallingNumber(s1[0]);
        callRecord.setAnswerNumber(s1[1]);

        //判断是否添加记录
        User callu=null,answeru=null;
        for(User u:users){
            if(u.getNumber().equals(s1[0])){
                callu = u;
            }
            if (u.getNumber().equals(s1[1])) {
                answeru = u;
            }
            if (callu != null && answeru != null) {
                break;
            }
        }
        if (callu != null) {
            if (callRecord.getCallType() == 1) {
                callu.getUserRecords().addCallingInCityRecords(callRecord);
            } else if (callRecord.getCallType() == 2) {
                callu.getUserRecords().addCallingInProvinceRecords(callRecord);
            } else {
                callu.getUserRecords().addCallingInLandRecords(callRecord);
            }
        }
        if (answeru != null) {
            if (callRecord.getCallType() == 1) {
                answeru.getUserRecords().addAnswerInCityRecords(callRecord);
            } else if (callRecord.getCallType() == 2) {
                answeru.getUserRecords().addAnswerInProvinceRecords(callRecord);
            } else {
                answeru.getUserRecords().addAnswerInLandRecords(callRecord);
            }
        }

    }
}
class User {
    private UserRecords userRecords;
    private double balance;
    private ChargeMode chargeMode;
    private String number;
    User(){
        userRecords=new UserRecords();
        balance=100;
    }
    public double calCost(){

        return chargeMode.calCost(userRecords);
    }
    public double calBalance(){
        return balance - chargeMode.getMonthlyRent() - chargeMode.calCost(userRecords);
    }
    public UserRecords getUserRecords() {
        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;
    }
}
abstract class ChargeMode{
    protected ArrayList<ChargeRule> chargeRules;
    ChargeMode(){
        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 ChargeMode{
    private double monthlyRent;
    LandlinePhoneCharging(){
        monthlyRent=20;
        chargeRules.add(new LandPhoneInCityRule());
        chargeRules.add(new LandPhoneInProvinceRule());
        chargeRules.add(new LandPhoneInlandRule());
    }
    @Override
    public double calCost(UserRecords userRecords){
        double sumCost=0;
        for(ChargeRule rule:chargeRules){
            sumCost+=rule.calCost(userRecords);
        }
        return sumCost;
    }
    @Override
    public double getMonthlyRent(){
        return monthlyRent;
    }
}
class UserRecords {
    private ArrayList<CallRecord> callingInCityRecords;
    private ArrayList<CallRecord> callingInProvinceRecords;
    private ArrayList<CallRecord> callingInLandRecords;
    private ArrayList<CallRecord> answerInCityRecords;
    private ArrayList<CallRecord> answerInProvinceRecords;
    private ArrayList<CallRecord> answerInLandRecords;
    private ArrayList<MessageRecord> sendMessageRecords;
    private ArrayList<MessageRecord> receiveMessageRecords;
    UserRecords(){
        callingInCityRecords=new ArrayList<CallRecord>();
        callingInProvinceRecords=new ArrayList<CallRecord>();
        callingInLandRecords=new ArrayList<CallRecord>();
        answerInCityRecords=new ArrayList<CallRecord>();
        answerInProvinceRecords=new ArrayList<CallRecord>();
        answerInLandRecords=new ArrayList<CallRecord>();
        sendMessageRecords=new ArrayList<MessageRecord>();
        receiveMessageRecords=new ArrayList<MessageRecord>();
    }
    public void addCallingInCityRecords(CallRecord callRecord){
        callingInCityRecords.add(callRecord);
    }
    public void addCallingInProvinceRecords(CallRecord callRecord){
        callingInProvinceRecords.add(callRecord);
    }
    public void addCallingInLandRecords(CallRecord callRecord){
        callingInLandRecords.add(callRecord);
    }
    public void addAnswerInCityRecords(CallRecord answerRecord){
        answerInCityRecords.add(answerRecord);
    }
    public void addAnswerInProvinceRecords(CallRecord answerRecord){
        answerInProvinceRecords.add(answerRecord);
    }
    public void addAnswerInLandRecords(CallRecord answerRecord){
        answerInLandRecords.add(answerRecord);
    }
    public void addSendMessageRecords(MessageRecord sendMessageRecord){
        sendMessageRecords.add(sendMessageRecord);
    }
    public ArrayList<MessageRecord> getSendMessageRecords() {
        return sendMessageRecords;
    }
    public ArrayList<MessageRecord> getReceiveMessageRecords() {
        return receiveMessageRecords;
    }
    public ArrayList<CallRecord> getCallingInCityRecords() {
        return callingInCityRecords;
    }
    public ArrayList<CallRecord> getCallingInProvinceRecords() {
        return callingInProvinceRecords;
    }
    public ArrayList<CallRecord> getCallingInLandRecords() {
        return callingInLandRecords;
    }
    public ArrayList<CallRecord> getAnswerInCityRecords() {
        return answerInCityRecords;
    }
    public ArrayList<CallRecord> getAnswerInProvinceRecords() {
        return answerInProvinceRecords;
    }
    public ArrayList<CallRecord> getAnswerInLandRecords() {
        return answerInLandRecords;
    }
}
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;
    CallRecord(String[] inputs) {
        super();
        if (inputs[0].length() == 10) {
            callingAddressAreaCode = inputs[0].substring(0, 3);
        } else {
            callingAddressAreaCode = inputs[0].substring(0, 4);
        }
        if (inputs[1].length() == 10) {
            answerAddressAreaCode = inputs[1].substring(0, 3);
        } else {
            answerAddressAreaCode = inputs[1].substring(0, 4);
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
        try {
            startTime = simpleDateFormat.parse(inputs[2] + " " + inputs[3]);
            endTime = simpleDateFormat.parse(inputs[4] + " " + inputs[5]);
        } catch (ParseException e) {
        }

    }
    CallRecord(Date startTime, Date endTime, String callingAddressAreaCode, String answerAddressAreaCode) {
        super();
        this.startTime = startTime;
        this.endTime = endTime;
        this.callingAddressAreaCode = callingAddressAreaCode;
        this.answerAddressAreaCode = answerAddressAreaCode;
    }
    public int getCallType() {
        if (callingAddressAreaCode.equals(answerAddressAreaCode)) {
            return 1;
        }
        if (callingAddressAreaCode.matches("^079[0-9]$") || callingAddressAreaCode.equals("0701")) {
            if (answerAddressAreaCode.matches("^079[0-9]$") || answerAddressAreaCode.equals("0701")) {
                return 2;
            }
        }
        return 3;
    }
    public Date getStartTime(){
        return this.startTime;
    }
    public void setStartTime(Date startTime){
        this.startTime=startTime;
    }
    public Date getEndTime(){
        return this.endTime;
    }
    public void setEndTime(Date 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;
    }
}
class MessageRecord extends CommunicationRecord{
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
abstract class ChargeRule{
    public abstract double calCost(UserRecords userRecords);
}
abstract class CallChargeRule extends ChargeRule{
    public abstract double calCost(UserRecords userRecords);
}
class LandPhoneInCityRule extends CallChargeRule{
    @Override
    public double calCost(UserRecords userRecords){
        double SumCost = 0;
        for(CallRecord call:userRecords.getCallingInCityRecords()){
            double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
            if(distanceS>0){
                double distanceM=(int)distanceS/60;
                if(distanceS%60!=0)
                    distanceM++;
                SumCost+=distanceM*0.1;
            }
        }
        return SumCost;
    }
}
class LandPhoneInProvinceRule extends CallChargeRule{
    @Override
    public double calCost(UserRecords userRecords){
        double SumCost = 0;
        for(CallRecord call:userRecords.getCallingInProvinceRecords()){
            double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
            if(distanceS>0){
                double distanceM=(int)distanceS/60;
                if(distanceS%60!=0)
                    distanceM++;
                SumCost+=distanceM*0.3;
            }
        }
        return SumCost;
    }
}
class LandPhoneInlandRule extends CallChargeRule{
    @Override
    public double calCost(UserRecords userRecords){
        double SumCost = 0;
        for(CallRecord call:userRecords.getCallingInLandRecords()){
            double distanceS=(call.getEndTime().getTime()-call.getStartTime().getTime())/1000;//getTime获取毫秒
            if(distanceS>0){
                double distanceM=(int)distanceS/60;
                if(distanceS%60!=0)
                    distanceM++;
                SumCost+=distanceM*0.6;
            }
        }
        return SumCost;
    }
}
class Common {
    public static double round(double m,int n) {
        return (double)Math.round(m*Math.pow(10,n))/Math.pow(10,n);
    }
}

idea生成类图:

SourceMonitor的生成报表内容:

因嵌套了太多的if/else导致代码几乎大部分都不合格,平均复杂度是15,远远超过绿色范围(所推荐的java良好代码,如平均复杂度在2.0-4.0之间)

第7次大作业

SourceMonitor的生成报表内容:

分析:判断字符串的合法性时用到了正则表达式。代码各类指标都良好,平均复杂度为3。

3-7-2 点线形系列2-线的计算

源码:

SourceMonitor的生成报表内容:

分析:代码主架构是switch里面有太多的if/else判断,导致部分指标不合格。

3-7-3 点线形系列3-三角形的计算

SourceMonitor的生成报表内容:

分析:主要问题和上面类似,不过平均复杂度更小。

采坑心得

1-7-2 长度质量计量单位换算

需要将doule类型转化成float类型后输出,如:

System.out.print((float)zl +" "+ (float)cd);

1-7-4 房产税费计算2022

输出时需要将结果转化为float类型,切忌不要出现(flaot)c*100.0,先将结果括起来再进行类型转换,或者先转化为double类型:

double f=b*5.0;//印花税
double g=d*3.0;//交易费
double h=d*1.36;//测绘费
System.out.print(" "+(float)f+" "+(float)g+" "+(float)h);

1-7-6 学号识别

建议用字符串输入,不要用int,要不然会变得不幸,别问我为什么知道。

1-7-9 二进制数值提取

输入区分使用next和nextLine,个人觉得nextLine会更常用,因为要判别空格等非法字符。

1-7-7 判断三角形类型

...PTA排序出错了。注意精度问题,判断是否为直角三角形:

Math.abs(a*a+b*b-c*c)<0.1//勾股定理

2-7-2 串口字符解析

注意输入的是字符串,进行单个字符比较时加上单引号或者减去某个数值,如下:

if((n+1)%2==s[j]-48&&s[j+1]!='1')//判断奇校验位和结束位

3-7-3 点线形系列3-三角形的计算

保留6位小数,且多余部分采用四舍五入规则进到最低位,参考如下:

S1=(double)Math.round(S1*Math.pow(10,6))/Math.pow(10,6);

涉及到0值判断的都应该考虑精度问题:

if(S1+S2+S3-S<1e-12)//面积相等

改进建议

可以将一些复用性较强的代码封装进自己的编辑器中,比如第三次大作业的点类,线类,三角形类都分别对应了三道小题,前两次作业基本上是简单的输入和输出,复用性不高,可以略过。

总结

1.前两次作业是练手的,目的是熟悉java基本语法;但是第三次作业工作量会剧增,而且类与类之间的联系以及类方法的复用性会增强,如果不对复用性强的代码封装成类,那么Main里面的代码将会变得特别混乱且长,你可能在第一个小问里写过同样的代码,下一问又要用上,没写类只能复制粘贴,而且观感特别不好,因为隔一段时间再去看根本不知道这部分代码实现了啥功能,我对此深有体会,因为我这三次作业都是一股脑全写在Main里面,提交通过后再把全部代码全看懂了再进行封装,花费时间太长了。
2.java时面向对象,而C是面向过程的,需要从C的编码习惯慢慢变为java的编码习惯,这个转化过程是漫长且煎熬的。

标签:return,String,double,ArrayList,PTA,计费,电信,public
From: https://www.cnblogs.com/DaMing5475/p/16969939.html

相关文章

  • pta第三次博客
    目录pta第三次博客1.前言2.设计与分析第6次作业第一题第6次作业第二题第七次作业第一题第七次作业第二题第七次作业第三题第八次作业第一题第八次作业第二题第八次作业第三......
  • Centos7.2 启用iptables
    一、防火墙iptables简洁介绍iptables和firewalld都是工作在用户空间、用来定义规则的工具,本身不是防火墙,他们定义的规则,可以让内核空间当中的netfilter读取,并且实现防......
  • iptables检查与删除策略
      [root@controller1~]#iptables-tnat-LPREROUTING--line-numbers#带序号查看指定表、链策略;小写字母对应表,大写字母对应链;-t指定表,-L指定链,--line-number......
  • 论文解读(PCL)《Probabilistic Contrastive Learning for Domain Adaptation》
    论文信息论文标题:ProbabilisticContrastiveLearningforDomainAdaptation论文作者:JunjieLi,YixinZhang,ZileiWang,KeyuTu论文来源:aRxiv2022论文地址:download......
  • c语言分支与循环pta练习题
    7-7高空坠球皮球从某给定高度自由落下,触地后反弹到原高度的一半,再落下,再反弹,……,如此反复。问皮球在第n次落地时,在空中一共经过多少距离?第n次反弹的高度是多少?输入格......
  • PTA-oop第三次博客2022.12.4
    一.前言 题目集六:本次大作业是第一次写电信计费,难度较前几次的多边形有了明显的下降,题目难点不再是算法的设计,而是类与类之间关系的设计,同样也是因为第一次写电信计......
  • Pta6-8次题目集总结
    前言对于这三次大作业,主要的难题就是电信计费系列的题目,以及接口的使用还有迭代器的基本使用,最后一次大作业还复习了之前的多态的内容。总体来说这三次大作业难度不大,题量......
  • 论文解读(CDTrans)《CDTrans: Cross-domain Transformer for Unsupervised Domain Adapt
    论文信息论文标题:CDTrans:Cross-domainTransformerforUnsupervisedDomainAdaptation论文作者:TongkunXu,WeihuaChen,PichaoWang,FanWang,HaoLi,RongJin......
  • 面向对象程序设计电信计费系列心得
      通过这几次的大作业,已经加强了封装函数和算法的实现,这次电信计费系列主要为通过已给类图实现功能,并没有太多算法设计和创新,但也有一些小问题和小设计存在,废话也不......
  • 贵阳电信金阳枢纽楼能耗管理系统的设计与应用
    安科瑞陈盼摘要:建筑能耗占整个世界能耗的30%以上。提高建筑能效是缓解全球变暖、提高环境可持续发展的一种有效方法。面对严重的能源和环境问题,中国政府在建筑节能领域采取......