(一)、前言
- 题目集六:
7-1:电信计费系列1-座机计费
难度:8
知识点:正则表达式,类的继承,抽象类的使用,抽象方法重写
7-2: 多态测试
难度:2
知识点:接口的实现、抽象方法重写,多态机制测试
- 题目集七
7-1 :电信计费系列2-手机+座机计费
难度:8
知识点:正则表达式,类的继承,抽象类的使用,抽象方法重写
7-2 :sdut-Collection-sort--C~K的班级(II)
难度:1
知识点:容器ArrayList元素的遍历,删除
7-3 : 阅读程序,按照题目需求修改程序
难度:1
知识点:使用集合存储3个员工的信息(有序); 通过迭代器依次找出所有的员工。
- 题目集八
7-1 :电信计费系列3-短信计费
难度:5
知识点:正则表达式,类的继承,抽象类的使用,抽象方法重写
7-2 : 编写一个类Shop(商店)、内部类InnerCoupons(内部购物券)
难度:3
知识点:内部类
7-3 : 动物发声模拟器(多态)
难度:2
知识点:使用集合存储3个员工的信息(有序); 通过迭代器依次找出所有的员工。
(二)、设计与分析
6-7-2题目分析:定义容器Container接口。模拟实现一个容器类层次结构,并进行接口的实现、抽象方法重写和多态机制测试。各容器类实现求表面积、体积的方法。
![复制代码](https://common.cnblogs.com/images/copycode.gif)
class Cube implements Container{ double a; @Override public double area() { // TODO Auto-generated method stub return 6*a*a; } @Override public double volume() { // TODO Auto-generated method stub return a*a*a; } }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
如上代码,Cube类实现Container接口,Cylinder类同理,重写所有抽象方法。
7-7-1题目分析:
在判断年月日格式的方法中用到SimpleDateFormat类;
学习到 try catch 语句的基本使用
try {
最终肯定必须要执行的代码(例如释放资源的代码)
}
![复制代码](https://common.cnblogs.com/images/copycode.gif)
public static boolean TestyyyyMMdd(String string) {//判断格式年月日 boolean yes = false; DateFormat formatter = new SimpleDateFormat("yyyy.MM.dd"); try{ Date date = formatter.parse(string); yes = true; }catch(Exception e){ yes = false; } return yes; }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
在分析手机区号的所在地的方法中,我一开始设计的是将字符串转为数字或者将数字补齐前面的零与字符串比较;
但是发现所涉及的方法太多,实际上根本用不着大费周章,但是学到一点新知识也是好的,可以尝试着用用看;
String的valueof()方法用于数字转字符;
String的format ( ) 方法可将数字的字符补全前面的零;
![复制代码](https://common.cnblogs.com/images/copycode.gif)
public static int where(String s) {//返回值:1为市内,2为省内,3为省外 // int i = 0; // int [] jxs = new int [11]; // String [] jxs1 = new String [11]; // String [] jxs2 = new String [11]; // for( i = 0; i<10; i++) // jxs[i] = 790 + i; // jxs[10] = 701; // for(i = 0; i<11; i++) // { // jxs1[i] = String.valueOf(jxs[i]);//数字转字符 // jxs2[i] = String.format("%04d", jxs1[i]);//字符补全0 // } // // // if(ssss.equals("0791")) // where = 1; // else { // for( i = 0; i<10; i++) // if(ssss.equals(jxs2[i])) // { // where = 2; // break; // } // } int where = 3; String ssss; if(s.length()>=4) { ssss = s.substring(0, 4); if(ssss.equals("0791")) where = 1; else if(ssss.equals("0701") ||ssss.equals("0790") ||ssss.equals("0792") ||ssss.equals("0793") ||ssss.equals("0794") ||ssss.equals("0795") ||ssss.equals("0796") ||ssss.equals("0797") ||ssss.equals("0798") ||ssss.equals("0799") ) where = 2; } return where; }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
如下代码,PhoneAnsweringLandRule 类继承抽象类 CallChargeRule重写方法;
原本写的时间计算方法是将时间相差的时、分、秒分别相减,若秒差大于零,意味着分钟数要多积一分;
但是这个计算方法仅仅局限在一天的范围内,没有考虑到跨天、跨月、跨年的情乱;
所以在查找资料后发现可以直接用Date的getTime()方法返回时间的差值;
![复制代码](https://common.cnblogs.com/images/copycode.gif)
// double a = callRecords.get(i).getEndTime().getHours()-callRecords.get(i).getStartTime().getHours(); // double b = callRecords.get(i).getEndTime().getMinutes()-callRecords.get(i).getStartTime().getMinutes(); // double c = callRecords.get(i).getEndTime().getSeconds()-callRecords.get(i).getStartTime().getSeconds(); // if(c>0) // m1[i] = a+b+1; // else // m1[i] = a+b;
![复制代码](https://common.cnblogs.com/images/copycode.gif)
callRecords) { double s1 = 0; int k = callRecords.size(); double [] m1 = new double [k]; double m = 0; int i = 0; for( ; i<callRecords.size();i++) { long miao = (callRecords.get(i).getEndTime().getTime()-callRecords.get(i).getStartTime().getTime())/1000; m1[i]=miao/60;//分钟 if(miao%60!=0) m1[i]+=1; m = m + m1[i]; } s1 = m*0.3; return s1; } }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
7-7-2题目分析:
1:删除Arraylist中重复的Student对象
通过不断地测试发现,ArrayList的元素删除方法remove存在问题,通过查找资料发现,不能遍历到最后一个元素达到删除的效果
通过在循环中添加一个 j - - 的语句,以达到删除重复元素的目的。
![复制代码](https://common.cnblogs.com/images/copycode.gif)
for(i = 0; i<stu.size(); i++) { for(int j=i+1;j<stu.size();j++) { if(stu.get(i).num.equals(stu.get(j).num)) { stu.remove(j); j--; } } }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
7-7-3:按照题目需求修改程序
如下代码修改处:
1. Iterator.hasNext()方法的正确书写格式
2. 将Iterator类型强制转换为Employee类型
![复制代码](https://common.cnblogs.com/images/copycode.gif)
// 2、创建迭代器遍历集合
Iterator it = c.iterator();
//3、遍历 while (it.hasNext()) { //4、集合中对象未知,向下转型 Employee e = (Employee) it.next(); System.out.println(e.getName() + "---" + e.getAge()); }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
8-7-1
做题过程中发现正则表达式还需要继续学习:
如下代码,通过正则表达式判断短信的输入格式是否正确;
一开始并不知道英文句号是特殊字符,所以在测试点中有很多都没有拿到分;
而英文逗号不特殊,正则判断可以直接写,但是句号就必须要在前面添加转义字符//
总之这里用到的表示:
boolean Testmessage2(String s) { boolean m = false; if(s.matches("m-\\d{11} \\d{11} ([A-Z]|[a-z]|[0-9]|\\s|,|\\.)+")) m = true; return m; }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
如下代码,SendMessageRule类继承抽象类MessageChargeRule,重写calcost方法;
一开始理解错了题目计费的意思,没有意识到是在短信三条五条为界限的区间中叠加计费;
后来发现后用 if else 语句嵌套实现;
而短信数量的计算要先判断 messageRecords) { double cost = 0; int n = 0;//一共多少条信息 int [] m = new int [messageRecords.size()];//每条信息记为几条 for(int j=0; j<messageRecords.size();j++) { if(messageRecords.get(j).getMessage().length()%10==0) m[j] = messageRecords.get(j).getMessage().length()/10; else m[j] = messageRecords.get(j).getMessage().length()/10+1; n = n + m[j]; } if(n<3) cost = n*0.1; else if(n<5) cost = 0.3+(n-3)*0.2; else cost = 0.3+0.4+(n-5)*0.3; return cost; } }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
在设计过程中,发现测试样例都能过但是不能拿到满分,在反复探索后发现忽视了一种重要问题:
我原来将输入的字符串用split方法剔除 - 和 空格 ,切割放入字符串的数组,但是如果用户发送的短信内容中也含有空格和-,则会将短信内容也分割,从而直接忽略了数组后面的内容;
所以我再创建新的字符串数组,保存短信内容;
但是需要注意的是,切割后数组中保存在第一个的元素为空,短信内容的字符串保存在第二个位置;
mr.setMessage(ss[1]);//短信内容
![复制代码](https://common.cnblogs.com/images/copycode.gif)
else if(Testmessage2(s)) { PhoneCharging p = new PhoneCharging(); String [] num2 = s.split("-| "); String[] ss = s.split("m-\\d{11} \\d{11} "); for( j = 0 ; j < users.size();j++) { if(num2[1].equals(users.get(j).getNumber())) //匹配用户号码 { MessageRecord mr = new MessageRecord();//该用户的某一个短信记录 mr.setCallingNumber(num2[2]);//短信发送至 mr.setMessage(ss[1]);//短信内容 users.get(j).getUserRecords().addSentMessageRecords(mr); } } }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
8-7-2
此题较为简单,只需要按照题目要求在测试类Main中,创建一个Shop类的对象myshop,从键盘输入一个整数(大于或等于3),将其设置为牛奶的箱数。假定有顾客分别使用了该商店面值为50的购物券、面值为100的购物券各消费一次,分别输出消费后商店剩下的牛奶箱数。
![复制代码](https://common.cnblogs.com/images/copycode.gif)
import java.util.Scanner; public class Main { public static void main(String[] args) { Shop myshop = new Shop(); Scanner input = new Scanner(System.in); int n = input.nextInt(); myshop.setmilkCount(n); myshop.counpons50.buy(); myshop.counpons100.buy(); } } class Shop{ private int milkCount; InnerCoupons counpons50 = new InnerCoupons(50); InnerCoupons counpons100 = new InnerCoupons(100); public void setmilkCount(int x){ this.milkCount = x; } public int getmilkCount() { return this.milkCount; } class InnerCoupons{ public int value; InnerCoupons(int x){ this.value = x; } public void setvalue(int x) { this.value = x; } public void buy() { setmilkCount(milkCount-value/50); System.out.println("使用了面值为"+value+"的购物券进行支付"); System.out.println("牛奶还剩"+milkCount+"箱"); } } }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
(三)、踩坑心得
1.没有注意 Date类的基本方法的使用;
2.字符串的substring用法没有记清楚;
3.SimpleDateFormat类的运用不熟练;
4.try catch 的使用不是很清楚,还需要继续认真学习;
5.没有根据数据控制输出格式。
6.正则表达式知识较多还需要多样的学习.
(四)、改进建议
- 可以多学习一些处理电信计费的数据更为方便的数学技巧,能避免很多问题,实质性内容更明显。
- 多去找问题发现问题,反思总结前面代码是否合适,不要怕推翻重来。
- 多考虑主类和子类的关系,处理好各种调用,思路和表达都要清晰有条理,代码才能看得舒心,用的放心。
- 注意double精度问题,时刻考虑将运算结果强制转化成float类型,否则数据不准确
- 多查找资料多请教同学,掌握的越多,大脑储备更全,以应对解决任何未知问题。
(五)总结
这次实验我学习到了很多,也发现了自己的很多问题,以及认识到了一些基础知识的缺乏。认识问题不够透彻,靠主观臆断试错,而不是先查询资料搞清楚.通过此次实验,我深刻认识到Java基本知识的重要性,并且学习到很多有用的知识,还锻炼了更加仔细探究问题的能力。在调试过程中,我发现有很多不懂的地方,绞尽脑汁也不清楚自己问题出现在哪,只能查找相关资料一步一步慢慢学习新知识,并将旧知识加以巩固。认识到我的各种不足后,我也会更加细致,多学习,多积累,遇到不懂的多借助网上资源进行自学。此外,在学习方法方面,我认识到应该提前清晰地计划好要解决的部分,不能将许多bug堆在一起等着之后再一个一个解决,否则会酿成不可预料无法挽救的可怜局面。总之,学习编程要时刻保持严谨的学术态度,细致认真脚踏实地才能有所建树.
标签:ssss,String,int,double,equals,BLOG,new From: https://www.cnblogs.com/balabala-la/p/16972372.html