1.)第一次作业主要是一些小的算法题难度低
2.)第二次作业主要是在点菜1和点菜2其他的题参考价值不大,两道题不算难但是要打好框架,不然点菜3不好写
这里的话我主要还是分析一下三道点菜,以及第二次的一道算法题,其他的就不多赘述。。。。。。
总体来说这几次作业还是对Java的学习有较大的帮助的,需要认真对待
比较简单,先贴代码
1.)分隔符操作:算是头一次用,其实菜单1可以不用分隔符操作的,但是之后的题目里没有它是不行的,所以为了架构更清晰,菜单1我也加入了分隔符操作,
String[]split=s.split("");对于这个操作是定义一个叫split的字符串数组,分割的就是s这个字符串,他将分割得到的几个字符串存进数组里,方便我们对输入的信息判断,
""之间的就是我们要的分割字符,这意味着字符串之间以该字符进行分割,在这里我们需要空格作为分割符,获取订单的信息,分别是菜名和份额。
2.)类型转换操作:portion=Integer.parseInt(split[1]);这里是因为分割得到的一定是字符,但是实际上它表示的是份额,这是个整数,所以需要进行类型转换,这里给出了
Integer.parselnt就是字符类型转整数类型的前缀,相较于c语言,不是很好记,要多用。
3.)逻辑思路:第一次太简单了,没有什么出错点,所以来梳理一遍整个的思路
首先在Dish类里我们定义了菜品的所有属性,包括它的名字,份额,计算价格的方法,接着在Menu里写个Dish的数组,目的是存菜单上的菜品,题目里已经给了,直接存
然后Record类,及菜品记录类,存下用户点的菜品的名字和对应的份额,这个相对于Dish多了一个用户输入的菜品份额,其实就是一个Dish2.0,然后因为用户点的菜不止一个,
所以我们用Order类保存所有的点菜记录,Order里开一个Record类的数组就行了,然后对应的在输入一条点菜记录的时候我们需要把它存进Record数组里,因此Order里需要一个
方法addARecord来实现这个功能。那最后就是将Order种Record数组的菜品记录的价格进行求和,同样在Order里有一个计算总价的方法getTotalPrice来实现这一功能。
Ps:)第一次菜单计价虽然简单,但是它让我们意识到了面向对象的真正内核:封装。事实上我们可以用c++(不是面向对象)直接完成这道题,但是当一个系统变得复杂,面向过程
的代码不仅难以修改和维护,而且会让事情变得复杂难以琢磨,甚至眼花缭乱(比如菜单3,就很难完成了),所以,面向对象的重要性就体现出来了,我们看似再做一些无用功,
其实是让代码变得结构清晰,各个功能独立且完善,这样在下一次进阶的点菜系统中就可以很轻松的完成修改,所以接受面向对象的思维是很重要的。
1.菜单计价程序2
代码如下:
下面是类图:
1.)题目变化:在菜单计价1中,菜谱是已知的,一共四道菜,但是这一次的题,菜谱要从键盘输入,那么有一个问题:什么时候输入的是菜谱,什么时候是点菜记录?
这是我们主要要考虑的问题。其次,用户可以进行删除某条订单的操作,我们要实现这一功能。
2.)输入类型判断:可以看到在菜单计价2的代码中我们新增了Transform的类,这个类是转换的意思,也就是根据不同的输入转化成对应的数字,并根据它进行下一步的操作
这个类的代码实现同样是通过分隔符来实现的,我们已经知道订单是有单号的,而菜谱输入没有,区别在于分割出的第一个字符串是不同的,菜谱的第一个字符串是一个菜名,
也就是汉字,点菜记录的第一个字符串实际上是一个数字,所以我们可以获取字符串的首字符,若首字符的ASCII值是49到57之间就说明是个数字,我们返回2或者3,菜谱的情况返回1
。因为有删除订单的操作,所以我们不知道返回2(订单),还是3(删除),所以要对第二个字符串进行判断,如果第二个字符串是delete那么就返回3,否则返回2。
3.)遇到的问题:起初我是打算将分割到的第一个字符串转化成数字,对数字的范围进行判断,但是汉字不能转换为数字,所以会报错,这点需要注意。
ps:)相比较于菜单1,其实变化不大,只要细心一点就可以,注意一下传参数时的非零返回就好,因为很难找,最好写的时候就注意,还有Transform的创建,这可以大大节省我们
处理输入的数据的代码,也使代码逻辑更加清楚。
2.小明走格子问题
原题如下:
从A点到B点有n个格子,小明现在要从A点到B点,小明吃了些东西,补充了一下体力,他可以一步迈一个格子,也可以一步迈两个格子,也可以一步迈3个格子,也可以一步迈4个格子。
请编写程序计算小明从A点到B点一共有多少种走法。
分析:这就是一道斐波那契数列变式的问题,大多数人都能写出来,我之所以提这道题主要是因为它是一种最基础的dp算法,虽然和面向对象无关,但是算法方面的东西还是想提一下
dp是什么?dp也叫动态规划,动态规划是运筹学的一个分支,是求解决策过程最优化的数学方法。利用各个阶段之间的关系,逐个求解,最终求得全局最优解,需要确认原问题与子问题、
动态规划状态、边界状态、边界值状态、状态转移方程。对于这道题,小明到第n个台阶的走法等于到第(n-1)、(n-2)、(n-3)、(n-4)个台阶的走法之和
所以状态转移方程就是a[i]=a[i-1]+a[i-2]+a[i-3]+a[i-4];
还是先放代码:
1.)题目变化:相对前两次的菜单计价程序,这次的题目明显复杂许多,在菜单计价程序2的基础上,添加了桌号,也就是说订单不再是只对一个用户,而是对若干桌的顾客,而且桌号的条件下
点菜的桌号顺序依次输出每一桌的总价。
3.)理清逻辑:首先桌号的出现使得我们的Transform类需要再加两种判断,一种是桌号信息的输入,另一种是代点菜信息的输入,判断不难,分割的第一个字符串如果是table,就是桌号信息
,不计算价格,至于日期类就不说了,判断是否是周末以及计算折扣的类。在这些之中处理table信息是最复杂的,我们需要知道哪一部分的订单时这一桌的,因此我在Mian里写了一种特殊的
方法来解决这一问题,比较偏向算法,没有进一步地封装,算是一点需要改进的地方。
分析:解决的思路各有不同,我的想法是先对单价乘份额后用一个整数保存它的整数部分,然后比较整数部分和它本身的差值是否小于0.5,若小于则取其整数部分,否则取整数部分加1
其实总的来说三次题目都不算很难,我觉得最多的还是Java里有许多简洁的操作对实现代码有帮助,需要一边写一边去查阅资料,不能心急,其次就是非零返回的问题,主要出现在将订单记录
和桌号记录存进数组里,以及查找一条菜品是否存在的处理上,最后就是要细心吧,因为测试点很多,要保证一个系统的完善就要非常细致。
1.修改日期类,使其更加准确,并加入注释方便阅读和以后的修改。
2.主函数里定义了许多变量用来处理每一桌的信息的分割和储存,这部分代码有改进的较大空间,可以将代码封装性加强。
3.一个完善的系统应该可以加入保护信息或者反馈错误的功能,可以自己尝试实现。
因为写项目和写算法是截然不同的,以前我只喜欢算法,说以学习面向对象的时候是有些排斥的,但是写完这三次题目后我已经能够很好地接受面向对象的思想了。
附:感谢老师老师的严格要求才使我能不放松不懈怠,最后在写题目中提升自己的能力。