Yqw的第一次博客作业

发布时间 2023-04-01 23:22:56作者: 22206130
# Yqw第一次博客作业
#
### 前言
####1.关于Java&面向对象
这个学期才开始接触Java以及面向对象,自我感觉和上学期接触的面向过程有很多的不同,一些基本的语法是相似的,但是也有很大的不同,给我感触最深的是类,开始以为它差不多就是函数,接触之后发现我一开始还是太天真了。
Java语言作为面向对象的编程语言,提供了面向对象的四种基本性质:抽象性、封装性、继承性和多态性。万事万物皆对象,Java面向对象编程是以人类最好理解的方向去编程(客观世界中的对象为中心)。
####2.关于三次作业
从开学至今吧,已经做了三次pta的作业。
第一周主要知识点应该就是substring和char.At()等一些和字符串有关的操作,同时也熟悉了简单的输入输出,改变了c语言的一些习惯,真的就是让我们熟悉熟悉Java这个语言的一些最基本的东西。第一次题量是最多的一次,虽然不太难,但是我记得我也没拿满分,有几个边界值的测试点一直没过去。开始的时间也不是太早,最后两天开始的吧,所以直到截至都没有改出来。
第二周主要就是接触菜单计价类和Java中日期类的基本使用,看过了Date、Calendar、SimpleDateFormat等包,还了解了throws IOException,throws是方法可能抛出异常的声明,某些情况下可用于避免运行超时。第二次作业的题量是最少的,难度感觉就是呈直线上升了,那个菜单计价程序真的是不是很明白,拿到7-1的分都是朋友花钱报了课,给我也分享了一下她的课程,才写出来的,但是还是一知半解。得分而言也可以说是不堪入目,如果不是延长时间可能就只能拿到十几分。
第三周的知识点比较杂,包括了LinkedHashSet的原理,让我了解了一点封装性的知识,我还使用了replaceAll、splits、DateFormat、ParseException等方法去做题。题量还行,我还专门花时间了解了Arraylist的一些知识点,算是对其有了初步的了解,但是还是没能写出菜单计价程序。就得分情况而言,是比第二次作业要好许多的。但是老实说难度也没比第二次差,就是心态和状态可能调整地好了一点,第二次到后面几天没搞明白,那个时候整个人都是崩溃的。

### 设计与分析
##### 菜单系列完整的代码,只有题目集2的7-1,习题二的7-2和习题三的7-1都没能完成,7-1根据老师给的类的模拟进行设计。下面主要分析了几个影响比较深的题目。

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

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

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

参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
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)
//添加一条菜品信息到订单中。
}

输入格式:
每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。

输出格式:
订单上所有菜品的总价(整数数值),每份菜
如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名

```
import java.util.Scanner;
/*
*主要完成数据的读取操作
*/
public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] caidan = new String[50];//创造一个数组
        int i = 0;
       
        while(true) {
            String dan =sc.nextLine();//输入每一行临时放在dan
            if(dan.equals("end")) {//读取到end时终止输入
                break;
            }
            caidan[i] = dan;//把输入的每一行放入caidan数组中
            i++;//数组元素的变化
        }
       
        Order order = new Order();
       
        for(String caipin:caidan) {//历遍数组caidan,caipin为循环中使用的一个任意自定义名
            if(caipin==null) {
                break;
            }
            String name = caipin.split(" ")[0];//读取分隔符“ ”前的字符
            int portion = Integer.valueOf(caipin.split(" ")[1]);//读取分隔符“ ”后的字符
           
                Menu menu = new Menu();
           
            Dish dish = menu.searchDish(name);
            if(dish==null) {
                System.out.println(name+" does not exist");
                //error=error+name+"不存在;";
            }else {
                order.addARecord(name, portion);
            }
           
        }
        System.out.println(order.getAllPrice());
    }
}
    /*
    菜品类:对应菜谱上一道菜的信息
    */
    public class Dish {
    String name;//菜品名称
    int unit_price; //单价
   
    public Dish(String name, int unit_price) {
        super();
        this.name = name;
        this.unit_price = unit_price;
    }

    //计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
    int getPrice(int portion){
        if(portion==1) {
            return unit_price;
        }
        else if(portion==2) {
            return (int) Math.round(unit_price*1.5);
        }
        else if(portion==3) {
            return unit_price*2;
        }
        else {
            return 0;
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getUnit_price() {
        return unit_price;
    }

    public void setUnit_price(int unit_price) {
        this.unit_price = unit_price;
    }

    @Override
    public String toString() {
        return "Dish [name=" + name + ", unit_price=" + unit_price + "]";
    }
   
}

/*
菜谱类:对应菜谱,包含饭店提供的所有菜的信息
*/
    public class Menu {
   
    Dish d1=new Dish("西红柿炒蛋",15);
    Dish d2=new Dish("清炒土豆丝",12);
    Dish d3=new Dish("麻婆豆腐",12);
    Dish d4=new Dish("油淋生菜",9);
   
    Dish[] dishs= {d1,d2,d3,d4};
   
    public Dish searchDish(String disName) {
        Dish ds = null;
        for(Dish dish:dishs) {
            if(dish.getName().equals(disName)) {
                ds = dish;
                break;
            }
        }
        return ds;
    }
}

/*
点菜记录类:保存订单上的一道菜品记录
*/
    public class Record {
    Dish dish;
    int portion;
   
    public int getPrice() {
    return dish.getPrice(portion);
    }

    public Record(Dish dish, int portion) {
        super();
        this.dish = dish;
        this.portion = portion;
    }

    public Dish getDish() {
        return dish;
    }

    public void setDish(Dish dish) {
        this.dish = dish;
    }

    public int getPortion() {
        return portion;
    }

    public void setPortion(int portion) {
        this.portion = portion;
    }
}

/*
订单类:保存用户点的所有菜的信息
*/
public class Order {
        Record[] records = new Record[100];
    public int getAllPrice() {
        int sum = 0;
        for(int i=0;i<records.length;i++) {
            if(records[i]!=null) {
                records[i].getPrice();
                sum+=records[i].getPrice();
            }
        }
        return sum;
    }
   
    public Record addARecord(String name,int portion) {
        Menu menu = new Menu();
        Dish dish = menu.searchDish(name);
        Record record = new Record(dish,portion);
        for(int i=0;i<records.length;i++) {
            if(records[i]==null) {
                records[i] = record;
                break;
            }
        }
        return record;
    }
}
```


##### 小明走格子
从A点到B点有n个格子,小明现在要从A点到B点,小明吃了些东西,补充了一下体力,他可以一步迈一个格子,也可以一步迈两个格子,也可以一步迈3个格子,也可以一步迈4个格子。请编写程序计算小明从A点到B点一共有多少种走法。

输入格式:
输入包含多组数据,第一行为一个整数m,m不超过10000,表示输入数据组数。接下来m行,每行为一个整数n(保证对应的输出结果小于2 31),表示从A点到B点的格子数。
输出格式:
输出为m个整数,表示对于每组数据小明从A点到B点的走法数。
```
import java.io.*;
import java.util.Scanner;
 
public class Main {
    public static void main(String args[]) throws IOException{
        StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        re.nextToken();
        int m = (int)re.nval;
        int a[] = new int[10000];
        int b[] = new int[100];
        int i,j,x = 0;
        for(i=0;i<m;i++)
        {
            re.nextToken();
            a[i] = (int)re.nval;
            if(x < a[i])
                x = a[i];
        }
        b[0] = 1;
        b[1] = 1;
        b[2] = 2;
        b[3] = 4;
        b[4] = 8;
        for(i=5;i<=x;i++)
            b[i] = 2 * b[i-1] - b[i-5];
        for(i=0;i<m;i++){
            System.out.println(b[a[i]]);
        }

    }
}
```
不理解为什么,但是就是得这样写的感觉。最后一个测试点是靠那个throws IOException 过的,至于为什么就不知道了。好多方法都不太理解,然后就反复尝试,一遍遍运行,一遍遍修改,在使用中习惯,在习惯后理解吧。

##### 重复数据
1.去掉重复数据主要就是使用了LinkedHashSet这个类。
2.在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。
(你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。)

输入格式:
你的程序首先会读到一个正整数n,n∈[1,100000],然后是n个整数。
输出格式:
如果这些整数中存在重复的,就输出:
YES
```
import java.util.Scanner;
import java.util.ArrayList; // 引入 ArrayList 类
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.io.*;
public class Main{
    public static void main(String[] args)throws IOException{
 
        ArrayList<Integer> numbersList = new ArrayList<>(Arrays.asList());
        int i=0,a,n;
        Scanner sc =  new Scanner(System.in);
        n = sc.nextInt();
        for(;i<n;i++) {
            a=sc.nextInt();
        numbersList.add(a);}
        LinkedHashSet<Integer> hashSet = new LinkedHashSet<>(numbersList);
        if(hashSet.size()!=n){
                            System.out.print("YES");
            System.exit(0);
            }
            System.out.print("NO");
}
}
```
这道题的测试点到截至我都只过了三个,过了3过不了4,过了4过不了3。
截止之后要了同学的代码做参考,她们大多用的数组加set,把string用split分割到数组中,用size测list里的数据个数与数组里的比较。


#
#
### 踩坑心得
印象最深的一个bug是我在提交的时候,把所有的类都放在了一个Main下面,也就是那个花括号内,然后导致一直报多种错误,我自己已经写的有点晕头转向了,一时间压根没想到可能是花括号的问题,还反复改了一会自己的代码。最终是感觉问了所有能问的朋友和同学,才恍然大悟地改对了。

### 主要困难以及改进建议
最大的问题就是自学吧,不知道从哪学起,面对题目感觉什么都不会,网上的课大多是连贯性比较强的,要不然就是对写题没什么帮助,学习通上的视频大多是讲一些框架和概念,对我个人而言,我是觉得比较晦涩难懂的,而且就是有一点作用,但不大。
就我个人而言,希望老师或者同学能推荐一些好的学习视频或者博客,相互多分享一些遇到的问题,例如用什么方法过一个一直卡者的测试点之类的。
~有一个小期望就是能有一个类似结构的程序可以参考看看,能够知道我需要去学什么,有方向性一点。~

### 总结
经过这三次作业,我学习到了Java的基本操作,变量赋值运算、数组、list等,也了解到了许多字符串的相关知识点,初步了解了类间关系、类的定义与设计等。Java比自己设想的要难很多,和C语言的区别更是比预想大许多。在类的设计和方法的设计方面还是要多训练,锻炼自己的面向对象的一个思维能力,这样才能真正学会、学懂,并做到学以致用。


######  路漫漫其修远兮,吾将上下而求索。
###### 在我看来,最最最主要的,还是要有一个积极乐观的心态,代码出bug是常有的,有些时候我们甚至解决不了,但是不能就因为这个而放弃学习,我可能拿不到满分,但是我要拿到自己能拿到的分,这个学期还很长,要坚持学习。Fighting!