PTA题目集1-3总结
一、 前言
不知不觉java已经学习了三个星期了,在学习的过程也收获了不少,由于有C语言的铺垫,语法变化不是很大,如递归,选择,循环,和C语言中的类似,使得在学习语法的过程中比较轻松。但是在更重要的是面向对象的加入,在解决问题的思路和方法上与C语言截然不同,使得程序的编写难度陡然提高。在java中引入了类的概念,类中包含属性和方法,使得整个程序系统性更强,模块更加清晰,虽然可读性加强,但是构思起来不如之前顺畅,不能达到一路到底的效果。
Java部分类里的函数让我这个程序小白大开眼界,比如String类中split()可以很容易地分割字符串, Integer类中parseInt()可以将字符串类型转化成整型,还了解了LocalDate类中of()、isAfter()、isBefore()、until()等方法。这些函数极大地简便了我的代码,缩短了我的完成时间。
最难的莫过于点菜系统的建立了。在点菜系,统中建立了菜品类,菜谱类,点菜记录类,订单类,等四个类,并且类与类之间互相连通,类里面还有属性和方法,导致了难度的加大。
难度:其他涉及语法的知识点并不难,可以通过C语言的经验和csdn上的资源提供帮助,让程序简单明了。当遇到菜单等涉及类的内容的时候,难度陡然增加,整个系统如一块巨大的蜘蛛网,如果有一点错误,可能会影响到整个程序的正常运行。
题量:餐馆点菜题,一题更比七节强;两道点菜题,一半人无从下手。
方法:
作业1:
7-1 身体质量指数(BMI)测算 / 7-2 长度质量计量单位换算:
Scanner in=new Scanner(System.in);(输入的定义)
double weight = in.nextDouble();(输入不同类型的内容需要不同的next类型)
7-3 奇数求和:for循环(C语言老知识点)
7-4 房产税费计算2022 :double类型转换成float类型(C语言老知识点)
7-5 游戏角色选择:switch case(C语言老知识点)
7-6 学号识别:
a.length()(C语言老知识点,可以得到a字符串的长度)
String b=a.substring(0,2);(substring函数可以对字符串a的内容进行截取,并且传给b中)
b.equals(a)(两个字符串的比较)
7-7 判断三角形类型:System.exit(0);(程序提前终止)
7-8 巴比伦法求平方根近似值:Math.abs(调用有关数学函数的类)
7-9 二进制数值提取:
String x=input.nextLine();
String x=input.next ();(next和nextLine之间的截止条件不同:next()遇到空格停止nextLine遇到回车停止)
作业2:
7-1 7-2 菜单计价程序:
Menu j=new Menu();
Dish k=new Dish();
Order l=new Order();
Record m=new Record();
(类的建立,调用,和属性,方法的建立,并将它们形成一个完整的系统,并且可以做到类里面套用类。)
7-3 jmu-java-日期类的基本使用:
year=Integer.parseInt(data1.substring(0,4));(可以将字符串中指定位置中的字符转化成int形式)
7-4 小明走格子:
StreamTokenizer input = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
input.nextToken();
int n = (int)input.nval;(这种方式可以显著地加快读取数据的速度)
作业3:
7-1
7-2 有重复的数据:
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)(双循环的熟练运用,可以比较容易地找到重复数据,但是比较耗时间)
7-3 去掉重复的数据
(相比于上面的方法进行了改进,每输入的那个数字分别对应一个数组,如果有重复的就在它的基础上+1,这样相比于双循环节省了大量的运行时间)
7-4 单词统计与排序:
str.split("\\,|\\ |\\."); / str.split(" ”);(对字符串进行分割,以括号里的字符为分界线,并且分割后的多个字符串自动形成字符串数组,使用起来特别方便)
a.compareToIgnoreCase(b)(对两个字符串的大小进行比较,并且不区分字符串的大小写)
7-5 面向对象编程(封装性):
建立以Student为核心的类,并进行Student中属性数据的输入,同时在类里建立方法来对数据进行传值,最后定义输出的操作。
7-6 GPS测绘中度分秒转换:System.out.printf("%.6f",d);(java也可以用printf的形式对内容进行输出,并且也可以控制浮点数的位数)
7-7 判断两个日期的先后,计算间隔天数、周数
LocalDate da1 = LocalDate.of(a1, b1, c1);(将时间变成标准格式,便于后期对数据的整理)
boolean status = da1.isAfter(da2);(对两个日期的前后进行比较,如果前比后大,则输出true,否则输出false)
Math.abs(da1.until(da2, ChronoUnit.DAYS))(计算两个日期相隔的天数)
Math.abs(da1.until(da2, ChronoUnit.WEEKS))(计算两个日期相隔的周数)
二、设计与分析
以第二次菜谱作业为例:
(1)菜谱类Menu:对应菜谱,包含饭店提供的所有菜的信息。
在菜谱类中,可以分成“添加菜品”和“根据菜名在菜谱中查找菜品信息”两个操作,并将菜品的名称和单价存入dish中。
(2)点菜记录类Record:保存订单上的一道菜品记录。
用户点餐时,每点一道菜时,都会选择不同的菜名、份额和份数。循环输入完这些内容后,要将每道菜的具体信息存入Order中,进而保存订单上每一道菜的记录。
(3)菜品信息Dish:
Menu将菜谱的菜名,价格信息存入Dish中,而Dish又将菜品信息传给Record,起到枢纽的作用。
(4)订单类Order:
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。
delARecordByOrderNum(int orderNum)//根据序号删除一条记录
findRecordByNum(int orderNum)//根据序号查找一条记录
}
涉及这五个内容:保存订单每一道菜的记录;计算总价;添加信息,删除记录,查找记录(感觉这个查找记录有点多余)。
第三次作业和第二次作业大同小异,但是在第二次的基础上增加了桌号一类,不同桌的Order也有所不同。
另外在第三次作业中添加了带点菜的功能,因此不同的桌号之间也应有方法进行联系。
每一桌的类中时间也不一样,还要确定时间对订单价格的影响。
三、采坑心得(小问题)
一开始出现的致命问题:没有加public,即没有设置访问权限。
拓展延伸:Class具有public、protect、friendly、private四种访问访问权限:
1)public:在任何地方都可被使用
2)protect、private:除了它自己,没有任何class可以使用,所以class不能是
protected或private(inner class除外)
3) friendly:同一个package中的classes能用
(原文链接:https://blog.csdn.net/weixin_33397994/article/details/114033084)
在java中,null以小写形式表示,不是大写形式。
Java中无法自动地对数据进行四舍五入处理。Math.round()是Java中舍入数字的经典方法,可以直接返回整数。
一开始未加student{},以为这个东西没有用,事实上这是类里面传参的重要工具。
四、主要困难以及源码建议(大问题)
(1)类与类之间的关系
在写7-1,7-2的过程中,一开始我根本没想过用类的形式来写代码,打算一串代码写到底。但是在写程序的过程中发现一个问题:频繁地会出现非零返回。
非零返回有很多种原因,第一个原因就是程序过于繁琐,第二个原因就是调用了函数之后没有跳出这个函数。当时我通过搜集资料花了很长时间也没有解决这个问题,于是还是选择了类的形式。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}
当时是我第一次接触到类,对于这种类中套类的情况更是少之又少。
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice();
Record addARecord(String dishName,int
portion)
}
一开始在单独一个类的运用上问题不大,但是碰到类中套类就非常难了。Menu中包含dish,同时record中也包含dish,order中包含record。这种层层套娃让我理不清楚,导致思路混乱。所以在完成点菜程序之前,要画一张结构图对每
个模块进行整理,找好类与类,类与属性,类与方法之间的关系,这样问题才能迎刃而解。
(2)输入内容的循环和跳出循环
输入格式:(以第二次大作业7-2为例)
菜名+英文空格+基础价格(菜品记录格式)
序号+英文空格+菜名+英文空格+份额+英文空格+份数(点菜记录格式)
序号 +英文空格+delete(删除记录格式)
最后一条记录以“end”结束。
由于输入的内容被分成了三个部分,即菜品,内容,删除。这三个部分又互相独立,在内部进行循环,所以跳出循环成了大问题。我写代码的时候跳出循环的方法是:当序号为1的时候跳出循环。事实上这种方法非常繁琐,因为本身序号也是各个类的属性之一,不仅要承担跳出循环的任务,同时也在类中发挥重要的计数和定位作用。
后面在我们班三位大佬的建议下,使用了计算数组长度的方法跳出循环。因为每个模块的输入的属性多少是不一样的,例如菜品记录格式中有菜名+基础价格两种属性,而点菜记录格式有序号+菜名+份额+份数等四份属性,英文空格充当分界线的作用,并运用split函数,将序号+菜名+份额+份数放入数组之中,计算该数组的长度,就可以确定哪些输入内容对应哪个模块了。
(3)运行时间的超时
在涉及要去除相同的数据时,大部分人想到的都是双循环。但是这种方法会显著会延长程序的运行时间。而且因为java是解释性语言,java程序在运行时类加载器从类路经中加载相关的类,然后jvm读取该类文件的字节,执行相应操作.而C++编译的时候将程序编译成本地机器码.一般来说java程序执行速度要比C++慢10-30倍。(来源于https://it.cha138.com/tech/show-1360889.html)
这两个原因导致我运行超时。
解决方案一:使用StreamTokenizer input = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
进行数据的输入可以极大地提高读取数据的效率。同时将双循环变为单循环,一个数字对应一个数组,如果有重复的就在它的基础上加1。(这种做法以前在c语言上用到过,不过忘了)
五、总结
这三次题目集,对C语言的循环,选择等内容进行了复习,但是由于C语言和java在编译过程中的区别(C语言是编译之后再运行,而java是一边编译边运行),导致java的运行时间远大于C语言的运行时间;其次是类的运用,将属性和方法都分割成了一个个小模块,主函数中的内容很少。对于类和属性和方法,我仍然有很多不懂的地方,特别是类中套类,很容易导致我的思路混乱。
改进意见:类的运用,说难也不难,说简单也不简单,但希望在完成菜单之前,能有一个例子来指引我们如何来完成。而且对于那些全新的知识点,应该给我们一段时间去学习那些语法,再去完成,这样能够学以致用。对于新学习的类和属性方法应进行整理,以笔记的形式进行呈现,使学习更有效率。
标签:总结,题目,java,int,记录,PTA,C语言,菜品,new From: https://www.cnblogs.com/Dut-/p/17279267.html