• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

gffg5559

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

OOP三次大作业总结-BLOG-1

面向对象程序设计三次大作业总结

一、前言。

 

第一次作业共有九道题目,都是考察Java的基础语法,我认为是用来让我们适应从C语言到Java的转变的(虽然我没做全对),没有运用上Java特色:类与对象;

 

第二次作业共四道题,随着学习进度的前进,我们也迎来了对象和类的学习,第二次作业用上了对象和类,还有方法,相对难度大大增加。其中,7-1和7-2的菜单计价程序,渗透到了面向对象的过程,类和对象的使用以及方法的构造等。主要难点在于:1.类的设计与使用:要根据题目要求设计出合适的类,每个类具有不同的属性、方法及构造方法,在程序中实例化这些类并调用其方法实现功能;2.字符串处理:输入的菜名和份额信息需要通过字符串处理来提取和解析数据,以便后续的计算和输出;3.控制流语句:程序需要正确地选择和执行分支语句、循环语句和跳转语句,以实现正确的用户交互和求解过程。7-4的小明走格子,我怎么都过不了运行超时的坎,后来通过查阅资料,发现可以用字符流输入(即一次只输入一个字符)实现该题,可以通过调用Scanner类的next()方法从控制台读取下一个单词,并将该字符串转化为一个字符数组char[] input。然后将该字符数组作为参数传递给countWays方法,开始递归计算从起点到终点的所有走法总数。

 

第三次作业共七道题,第一题菜单我没写出来(冷汗冷汗),7-3去掉重复的数字运用了输入缓冲流方法,使用Java中的Set集合来实现去重,以及使用StringBuilder来进行字符串的拼接。Set是Java集合框架中的一种数据结构,它是一个不包含重复元素的集合,需要注意的是,当元素存在重复时,Set会自动去重,因此最终的结果不会包含任何重复元素。这种去重方法也比较高效,尤其适用于对大量数据进行去重的情况。7-5面向对象编程(封装性)则主要是对封装性的理解(说实话挺难理解的)。

 

二、设计与分析。

三道菜单计价程序问题的设计与分析:

1.菜单计价程序-1

1)类图:

 

 2)题目:

 

某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9

设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

 

3)分析:

Dish类:表示一个餐品,包括名字和单价等属性。其中 getPrice(int portion) 方法用于根据不同的食物数量计算对应的价格。

Menu类:表示菜单类,包括添加餐品,以及通过名称查找餐品等方法。

Record类:表示一条记录,即某个餐品和对应的数量组成的记录。其中 getPrice() 方法调用了 Dish 的 getPrice(int portion) 方法计算当前记录的价格。

Order类:表示订单类,包含记录数组,可以根据输入的餐品名称、数量以及菜单信息创建新的 Record 对象,并将其加入到记录数组中。同时,还提供了计算订单总价的 getTotalPrice() 方法。

 

2.菜单计价程序-2


1)类图:

 

2)题目:

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。


订单分:点菜记录和删除信息。每一类信息都可包含一条或多条记录,每条记录一行。
点菜记录包含:序号、菜名、份额、份数。
份额可选项包括:1、2、3,分别代表小、中、大份。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

 

 

3)分析:

Menu 类:此类负责管理菜单项,其中 addDish 方法可用于将新的餐品(具有名称和价格)添加到菜单列表中。另外, findDishByName 方法可用于查找指定名称的餐品。

Dish 类: 表示某一道菜品,包含了名称、单价等基本属性及操作方法。

Record 类:表示购物车中的一条记录,即某个餐品和对应数量组成的记录。其中 price 方法用于计算当前条目的总价格。

Order 类:表示订单,可以通过菜单和记录列表来创建一个 Order 对象。addARecord 和 delARecordByOrderNum 两个方法可用于添加或删除错误的记录。getTotalPrice 方法可用于获取整个订单的总价值。

 

3.菜单计价程序-3

 

1)类图:

 

 

2)题目:

 

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

3)分析:

代码的主要功能是管理餐厅点餐、结账以及生成报表。程序在输入过程中通过 Scanner 类来获取控制台上的输入信息,处理完成后将结果输出到控制台。

具体来说,该程序包含一个 Dish 类和一个 Table 类,Dish 类用于存储菜品名称和价格,而 Table 类用于存储桌号、日期、时间和订单信息等。程序主函数采用 while 循环来不断读取输入,根据用户输入执行相应的操作,直到用户输入 end 或 table 命令结束程序。

程序主体部分主要实现了以下功能:

  1. 解析输入并存储菜品信息:整个程序最开始先解析用户输入得到菜名及其对应的价格,并按输入顺序存储到 dishes 数组中。

  2. 获取输入中的桌号、日期、时间等信息:程序从输入中获取桌号、日期、时间等信息,并存储在 tables 数组中。

  3. 处理订单:程序读取用户输入中的“订单编号-菜品名称-份数-数量”信息,并按照特定的格式存储在 order 数组中,同时计算每个订单的总价并打印在控制台上。

  4. 结账:当用户输入 end 命令时,程序先遍历所有 tables,统计其中的所有订单价格总和,并输出结账信息。

三、采坑心得。

1.非法输入:

第一次作业7-9二进制数值提取:

  

import java.util.*;
import java.lang.*;
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        String str=input.nextLine();
        int Len=str.length();
        int Flag=0;
        for(int t=0;t<Len;t++)
        {
            if(str.charAt(t)=='-'&&str.charAt(t+1)=='1'){
                Flag=1;
                break;
            }
            if(str.charAt(t)=='0'||str.charAt(t)=='1'){
                System.out.print(str.charAt(t));
            }
        }
        if(Flag==0){
            System.out.println("Wrong Format");
        }
    }
}

 

这段代码存在问题是:对于长度为1的字符串输入时,访问了后面一个字符。

当输入长度仅为1的字符串时,在循环中判断if(str.charAt(t)=='-'&&str.charAt(t+1)=='1')会访问到字符串外面的内存空间,会产生StringIndexOutOfBoundsException异常。可以添加if(Len==1) return;来避免这个问题。

 

2.运行超时:

第二次作业7-4小明走格子:

 

 

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        while (m-- > 0) {
            int n = scanner.nextInt();
            int[] dp = new int[n + 1];
            dp[0] = 1;
            dp[1] = 1;
            if (n >= 2) {
                dp[2] = 2;
            }
            if (n >= 3) {
                dp[3] = 4;
            }
            for (int i = 4; i <= n; i++) {
                dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3] + dp[i - 4];
            }
            System.out.println(dp[n]);
        }
    }
}

在网上查阅的资料建议可以通过字符流输入(BufferedReader),来提升输入速度,从而减少运行时间;

还有的建议是使用滚动数组。因为dp[i]只与dp[i-1]、dp[i-2]、dp[i-3]、dp[i-4]有关,所以可以将数组中的元素不断往后移,并使用一个指针表示当前计算到的位置。这样可以避免不必要的空间浪费,从而降低时间复杂度。

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
while (m-- > 0) {
int n = scanner.nextInt();
int[] dp = new int[5];
dp[0] = 1;
dp[1] = 1;
if (n >= 2) {
dp[2] = 2;
}
if (n >= 3) {
dp[3] = 4;
}
int cur = 4;
while(cur <= n){
int next = dp[3] + dp[2] + dp[1] + dp[0];
dp[0] = dp[1];
dp[1] = dp[2];
dp[2] = dp[3];
dp[3] = next;
cur++;
}
System.out.println(dp[3]);
}
}
}

使用滚动数组后,只需要记录数组中最后四个元素,并随着计算不断往后更新,即可得到dp[n]的值。因此,在计算dp[i]时,只需要进行一次加法运算,而不需要再次访问前面的数组元素,从而降低了时间复杂度,避免了超时的问题。

 

四、主要困难以及改进建议。

主要困难:

1.菜单计价程序需要维护菜品的名称、价格、份数、总价等信息,需要建立相应的数据模型来存储和管理这些信息。如果数据模型设计不合理,会影响程序的可维护性、扩展性和性能。

2.在计算总价时,可能会出现精度丢失或者舍入误差等问题,导致计算结果与实际结果存在差异。为了避免这个问题,程序需要使用适当的数据类型和算法,并进行精度控制和错误处理。

3.如果菜单计价程序需要支持多用户并发操作,需要考虑多线程并发访问带来的数据一致性和安全性问题,并使用适当的同步机制进行控制。

4.菜单计价程序可能涉及到多个相似的功能模块,需要考虑代码复用和重构的问题,以提高代码的重用性、可读性和可维护性。这需要合理的设计架构和代码组织结构,并使用适当的设计模式和最佳实践。

 

五、总结。

 一、对代码:

对于Java代码,我自身是带有敬意的,因为C语言考试的不及格,多少对面向对象程序设计是抱有巨大的忧患意识的,所以在做作业的时候不敢怠慢。听老师的话先在IDEA(老师说也可以在eclipse)里先写好再复制粘贴到PTA里,我也听说了一些同学直接在PTA里写,(逻辑,运行等)错误百出,浪费了很多时间。虽然真的学得特别吃力,但我会认真听老师讲课,去看别人写的代码,看别人下很大功夫才想出来的设计和算法。

二、对自己:

只能说尽力去学吧,Java本身就是一个十分庞大的东西,不能全指望老师上课讲的那些语法,还要去找资源,自己去B站找视频看。也是听取了厉害大佬的建议:时刻提醒自己这门专业本身就不是以学习语法为重点。处理问题时一头扎进问题中,忽略其他细节,在错误的方向上疯狂进发,然后写出来一堆没意义的代码,为了避免这种情况发生,老师讲到的东西一定要注意,老师上课讲的某些点很不经意,但都是他这么多年写代码总结出来的经验,认真学吧,总有些收获!!!

三、对教师:

我的面向对象程序设计老师是罗老师,对我们很认真负责,上课也是一本正经地上,我只能说在他的课上有种回到高中的感觉……

四、对这门课:

个人认为这种形式还不错,课上老师输出大波干货,课下自己自行摸索,也有同学老师之间的交流协作过程,虽然这样挺辛苦,但吃得苦中苦方为人上人嘛

还有就是这门课的考查方式,不是像上学期C语言那样手写代码,而是真正地在笔记本上敲代码,考察编程能力,真的是泰裤辣!

posted on 2023-05-24 22:41  ultraman令  阅读(111)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3