题目集1~3的总结性Blog

前言:题目集1~3主要考察在学习c语言后,转而学习java时我们的自学能力,题目集的难度以及覆盖的知识点也是逐步递增的,相较于菜单计价系统系列的题目,题目集1的题目相对于简单,只需要在编写代码时注意方法的引用以及细节的把握,取得满分并没有太大的难度。题目集2的难度有所增加,尤其时菜单计价系统的引入,大大加深了作业代码的复杂度。其他的小题也需要更深入的java知识储备支撑才得以完成。题目集3的难度提升了一个档次,基础不牢的人是无法完成完整完成这次java作业的编写的。在这三次的作业中,代码的复杂度和代码量也是大幅度增加的。

题目集2    

7-3 jmu-java-日期类的基本使用

 

源码:

import java.io.*;
import java.util.Scanner;
import java.util.Calendar;
public class Main
{
    public static void main(String[] args) throws IOException
    {
        Scanner input = new Scanner(System.in);
        String s1=input.nextLine();
        String s2=input.next();
        String s3=input.nextLine();
        s3=s3.substring(1);
        int nian,yue,ri,tian1=0,tian2=0,tian3=0,t=0;
        int[] riqi= {31,28,31,30,31,30,31,31,30,31,30,31};
        if(judge(s1)==0)
            System.out.println(s1+"无效!");
        else
        {int r=0;
            nian=Integer.valueOf(s1.substring(0,4));yue=Integer.valueOf(s1.substring(5,7));;ri=Integer.valueOf(s1.substring(8,10));
            if((nian % 4 == 0 && nian % 100 != 0) || nian % 400 == 0 )
            {
                r=1;
            }
            if(r!=1&&yue==2&&ri>28)
                {System.out.println(s1+"无效!");t=1;}
            else if(r==1&&yue==2&&ri>29) {System.out.println(s1+"无效!");t=1;}
            else if(r==1) System.out.println(s1+"是闰年.");
            if (t!=1)
            {for(int i=0;i<yue-1;i++)
            tian1+=riqi[i];
            tian1+=ri;
            tian2=ri;
            tian3=calendar(nian,yue,ri);
            System.out.println(s1+"是当年第"+tian1+"天,当月第"+tian2+"天,当周第"+tian3+"天.");}
        }
t=0;
        if(judge(s2)==0||judge(s3)==0)
        { System.out.println(s2+"或"+s3+"中有不合法的日期.");t=1;}
        else if(run(s2)==1||run(s3)==1)
             {System.out.println(s2+"或"+s3+"中有不合法的日期.");t=1;}
        else if(s2.compareTo(s3)>0)
            {System.out.println(s3+"早于"+s2+",不合法!");t=1;}
        if(t==0)
        {
            int a,b,c,d,e,f;
            a=Integer.valueOf(s2.substring(0,4));b=Integer.valueOf(s2.substring(5,7));c=Integer.valueOf(s2.substring(8,10));
            d=Integer.valueOf(s3.substring(0,4));e=Integer.valueOf(s3.substring(5,7));f=Integer.valueOf(s3.substring(8,10));
            int year=d-a,mounth=e-b,day=0;
            for(int i=0;i<e-1;i++)
                day+=riqi[i];
            day+=c;
            for(int i=11;i>=b;i--)
                day+=riqi[i];
            day+=riqi[b-1]-f;
            day+=(year-1)*365;
            for(int i=a+1;i<d;i++)
                if((i % 4 == 0 && i % 100 != 0) || i % 400 == 0 )
                 day+=1;
                if((d % 4 == 0 && d % 100 != 0) || d % 400 == 0 )
                {if(e>2) day+=1;if(e==2&&f==29) day+=1;}
            if(a!=d)
                if((a % 4 == 0 && a % 100 != 0) || a % 400 == 0 )
                {if(b<2) day+=1;if(b==2&&c<29) day+=1;}
            day+=2;
            if(a==d)
                {day=0;
                for(int i=b-1;i<e-1;i++)
                    day+=riqi[i];
}
            System.out.println(s3+"与"+s2+"之间相差"+day+"天,所在月份相差"+mounth+",所在年份相差"+year+".");
        }
    }
    public static int judge(String s1)
    {
        int f=1;
        String nian,yue,ri;
        if(s1.length()==10)
        {
              for (int i = 0; i < s1.length(); i++)
              {
                  if(i==4||i==7)
                      continue;
                  else if (!Character.isDigit(s1.charAt(i)))
                        f=0;
                  else if(s1.charAt(4)!='-'||s1.charAt(7)!='-')
                      f=0;
              }
        }
        else f=0;
        if(f==1)
        {
            nian=s1.substring(0,4);yue=s1.substring(5,7);ri=s1.substring(8);
        if(yue.compareTo("13")>=0||ri.compareTo("32")>=0||yue.compareTo("00")==0||ri.compareTo("00")==0)
            f=0;
        }
        return f;
    }
    public static int run(String s1)
    {
        int r=0,t=0;
        int nian,yue,ri;
        nian=Integer.valueOf(s1.substring(0,4));yue=Integer.valueOf(s1.substring(5,7));;ri=Integer.valueOf(s1.substring(8,10));
        if((nian % 4 == 0 && nian % 100 != 0) || nian % 400 == 0 )
          r=1;
        if(r!=1&&yue==2&&ri>28)
            t=1;
        else if(r==1&&yue==2&&ri>29)
            t=1;
        return t;
    }
    public static int calendar(int nian,int yue,int ri)
{Calendar c=Calendar.getInstance();
c.set(nian,yue-1,ri);//设置时间

int d=c.get(Calendar.DAY_OF_WEEK)-1;
if(d==0)
    d=7;
return d;
    }
}

设计与分析:

这段代码实现了对日期的处理和计算,包括判断日期是否合法、闰年计算、以及计算两个日期之间的天、月、年的差值。下面来对这个程序进行更加详细的分析总结。

首先,这个程序使用了Scanner类读取用户输入的字符串,并分别将其转为三个字符串:s1, s2, s3。其中,s1表示将要被处理的日期(例如: 2022-01-31),而s2和s3则用于后面两个日期之间的计算。这些字符串存储在内存中,供程序进行判断和操作。

接着,程序通过judge方法对输入的日期s1进行有效性校验。如果输入的格式不正确或者日期存在逻辑错误,则打印无效信息并退出程序,否则进入正常的计算流程。该方法还专门针对年月日的范围进行了检查,以保证输入数据的正确性。

然后,通过run方法判断闰年。根据闰年的定义,只有符合4年一润、百年不润、四百年再润这三个条件,才被定义为闰年。通过这个方法可以确定某一特定年份是否为闰年,以便后续对日期的计算,进而精确地计算出两个日期之间的天数、月数和年数。

接下来,程序使用calendar方法获取当前日期是星期几。这个方法通过Java API中的Calendar类获取,首先通过Calendar.getInstance()获得一个Calendar对象,然后把年月日设置到这个实例中,最终调用get(Calendar.DAY_OF_WEEK)可以得到当天是星期几。

接着,程序开始计算两个日期之间的差值。其核心代码在main方法中,通过解析字符串中的年月日信息,使用for循环、数组等基本语法和逻辑运算实现了对日期的加减、比较等运算。值得注意的是,由于不同月份的天数并不相同,因此程序使用了一个整型数组riqi,来保存每个月份的天数,以便在进行日期加减运算时调用。

最后,在主方法中,判断输入是否正确,如果正确则输出计算结果,否则输出错误提示。整个程序的架构清晰明了,功能完备,实现了对日期的强大处理能力,并且考虑到了闰年等特殊情况的处理,具有很好的实用价值。

7-4 小明走格子

 源码:

import java.io.*;
import java.util.*;
 
public class Main {
    public static void main(String args[]) throws IOException{
        StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        re.nextToken(); 
        int T = (int)re.nval;
        int a[] = new int[10010];
        int b[] = new int[100];
        int i,j,maxx = 0;
        for(i=0;i<T;i++)
        {
            re.nextToken();
            a[i] = (int)re.nval;
            if(maxx < a[i]) maxx = a[i];
        }
        b[0] = 1;b[1] = 1;b[2] = 2;b[3] = 4;b[4] = 8;
        for(i=5;i<=maxx;i++) b[i] = 2 * b[i - 1] - b[i - 5];
        for(i=0;i<T;i++)
            System.out.println(b[a[i]]);
    }
}

设计与分析:

这道题主要重在理解,理解这道题的逻辑关系之后,代码的编写就简单很多,这段代码实现了一个数列的求解,通过输入一个整数T,表示有T个需要求解的数字,再输入T个整数a[i],表示需要求解的每个数字。程序首先计算出这T个数字中最大值maxx,然后利用递推公式b[i] = 2 * b[i - 1] - b[i - 5],求解出从0到maxx的所有数列值,并保存在数组b中。

算法思路非常简单,且代码量不多。但需要注意的是,在计算过程中需要考虑内存和运行时间等问题,保证数据类型的正确性和运算准确性来避免数据溢出和精度问题。需谨慎处理。

7-1 菜单计价程序-1

源码

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Dish[] dishes = {
                new Dish("西红柿炒蛋", 15),
                new Dish("清炒土豆丝", 12),
                new Dish("麻婆豆腐", 12),
                new Dish("油淋生菜", 9)
        };
        Menu menu = new Menu(dishes);
        Order order = new Order();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            String input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            }
            String[] parts = input.split(" ");
            String dishName = parts[0];
            int portion = Integer.parseInt(parts[1]);
            Record record = order.addARecord(dishName, portion);
        }
        System.out.println(order.getTotalPrice());
    }
}
class Dish {
    String name;
    int unit_price;

    public Dish(String name, int unit_price) {
        this.name = name;
        this.unit_price = unit_price;
    }

    public int getPrice(int portion) {
        double price = unit_price;
        if (portion == 2) {
            price *= 1.5;
        } else if (portion == 3) {
            price *= 2;
        }
        return (int) Math.round(price);
    }
}
class Menu {
    static Dish[] dishes;

    public Menu(Dish[] dishes) {
        this.dishes = dishes;
    }

    public static Dish searchDish(String dishName) {
        for (Dish dish : dishes) {
            if (dish.name.equals(dishName)) {
                return dish;
            }
        }
        return null;
    }
}
class Record {
    Dish dish;
    int portion;

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

    public int getPrice() {
        return dish.getPrice(portion);
    }
}
class Order {
    Record[] records;

    public Order() {
        records = new Record[0];
    }

    public int getTotalPrice() {
        int totalPrice = 0;
        for (Record record : records) {
            totalPrice += record.getPrice();
        }
        return totalPrice;
    }

    public Record addARecord(String dishName, int portion) {
        Dish dish = Menu.searchDish(dishName);
        if (dish == null) {
            System.out.println(dishName + " does not exist");
            return null;
        }
        Record record = new Record(dish, portion);
        records = Arrays.copyOf(records, records.length + 1);
        records[records.length - 1] = record;
        return record;
    }
}

设计与分析:

这段代码中使用了封装、继承、多态等面向对象的编程思想,使程序的结构更加清晰和易于维护。

其中,程序中定义了四个类:Dish、Menu、Record和Order。Dish类表示每一道菜品,包含名称和单价两个成员变量,以及获取某份菜品对应价格的方法。Menu类表示整个菜单,包含所有菜品,提供查找菜品的方法。Record类表示一条订单记录,包含菜品和数量两个属性,以及获取该记录对应总价的方法。Order类表示整个订单,包含若干个订单记录,提供增加订单记录、获取订单总价等操作方法。

除此之外,在主函数中通过Scanner读取用户输入,并使用字符串处理技术对输入进行解析和分割,以便调用相应的方法并返回正确结果。另外,程序还使用了数组、类型转换、循环、条件语句等各种控制流程语句完成相关操作。

总的来说,这段代码具有以下几个优点:

1.面向对象:采用类与对象的概念将不同的功能模块进行封装,使得代码结构更加清晰、逻辑更加明确、灵活性和可扩展性更好。

2.简洁易懂:代码中定义的类容易理解,函数名称也都比较以及整体代码布局条理清晰,可以使初学者轻松看懂其功能。同时它使用了Java语言中各种常用的控制流程和字符串处理技术等,使得代码更加简洁明了,便于维护和扩展。

3.实现了基本需求:针对点餐系统基本的需求,实现了查询菜品、计算菜品价格、生成订单,以及计算订单总价等程序的基础功能,并具有很好的稳定性和可靠性。

4.代码可读性强:代码中的变量命名、代码块缩进等方面做的非常好,具有良好的格式化规范性让程序员能够一目了然看懂代码,大大增加了代码的可读性和维护性。

虽然存在着一些不足之处,例如代码结构层次过于简单,没有严格的注释说明等问题。在之后的菜单计价系统系列里会加以改进。

心得:

这是我接触的第一次真正意义上的java大作业,编写的代码的灵活性与复杂性也不是以前能比的。要想完成这次作业的编写,就需要对java进行一定程度的自学与了解,在这段代码中引用了Arrays类和Scanner类,Arrays类的用法我还上网查阅了相关资料,Arrays类包含了各种用于操作数组的方法,

主要包括以下几个方面:

  1. 数组比较相关函数
  • equals():比较两个数组是否相等
  • deepEquals():比较两个多维数组是否相等
  1. 数组填充相关函数
  • fill():用特定值填充数组中的所有元素
  • setAll():使用指定的生成器函数为数组元素分配新值
  1. 数组排序相关函数
  • sort():对整个数组进行排序
  • parallelSort():对整个数组并行排序
  1. 其他操作数组的函数
  • toString():将数组转换成字符串
  • copyOf():复制数组
  • copyOfRange():复制数组的一部分
  • binarySearch():二分查找数组中的元素
  • asList():将数组转换成集合List

以上皆是我在本次作业中学习到的知识点。

7-2菜单计价程序-2

源码

import java.util.Scanner;

    /*输入:name表示菜品名称;unit_price是菜品价格;
    计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)*/
        class Main{
        public static void main(String[] args){
            int j=0,k,sum=0,i;
            String s;
            String s1;
            Scanner scanner=new Scanner(System.in);
            Order order=new Order();
            Menu menu=new Menu();
            while(true){
                s=scanner.next();//zuopanduan
                if(s.equals("end"))
                    break;
                if(s.charAt(0)-'0'<=100){
                    int orderNum=0,num=0,portion=0;
                    orderNum=s.charAt(0)-'0';
                    s1=scanner.next();
                    if(!(s1.charAt(0)!='d')) { //后续可能会有bug
                        if (order.findRecordByNum(order,orderNum, j) != 1)
                            System.out.println("delete error;");
                        else
                            order.delARecordByOrderNum(order,orderNum);
                    }
                    else {
                       int portion1=scanner.nextInt();
                       int num1=scanner.nextInt();
                       order.records[j]=order.addaRecord(menu,orderNum,s1,portion1,num1);
                        if(!(order.records[j].d!=null))
                            System.out.println(s1+" "+"does not exist");
                        else
                            System.out.println(order.records[j].orderNum+" "+order.records[j].d.name+" "+order.records[j].getPrice);
                        j++;
                    }

                }
                else {
                    int p=scanner.nextInt();
                    menu.addDish(s,p);
                }
            }
            for(i=0;i<j;i++)
                sum+=order.records[i].getPrice;
            System.out.print(sum);
        }
    }

       class Dish {
        String name;
        int unit_price;

        public Dish(String name,int unit_price){
            this.name = name;
            this.unit_price = unit_price;
        }
        public Dish(){
        }
        public int getPrice(int portion){
            double unit_price1=unit_price;
            if(portion==2)
                unit_price1=1.5*unit_price;
            if(portion==3)
                unit_price1=2*unit_price;
            return (int) Math.round(unit_price1);
        }
    }
    /*输入:dishs菜品数组,用来保存所有菜品信息;
    searthDish(String dishName)根据菜名在菜谱中查找菜品信息,返回Dish对象;参数类型为String,名称为dishName;
     */
     class  Menu {
       public Dish[] dishs=new Dish[20];
         int f=0;
         Dish searthDish(String dishName){
              int i;
            int flag=0;
            for(i=f-1;i>=0;i--){
                flag=0;
                if(dishs[i].name.equals(dishName)){
                    flag=1;break;
                }
            }
            if(!(flag != 1))
            return dishs[i];
            else
                return null;
        }
        public void addDish(String dishName,int unit_price){
               dishs[f]=new Dish(dishName,unit_price);
               f++;
        }
    }
    /*输入:d Dish类型的菜品;portion份额(1/2/3代表小/中/大份)getPrice()函数计价,计算本条记录的价格*/
    class Record {
        int orderNum;//序号\
        Dish d;//菜品\
        int portion;//份额(1/2/3代表小/中/大份)\
        int getPrice;
        int num;
    }


    class Order {
        Record[] records=new Record[20];
        //int getTotalPrice()//计算订单的总价
        /*Record addARecord(String dishName,int portion){       //写一条加一条
          Menu menu=new Menu();
          Record record=new Record();
         record.d= menu.searthDish(dishName);
         record.portion=portion;
         if((record.d!=null))
         record.getPrice=record.d.getPrice(portion);
          return record;
        }*/
        public Record addaRecord(Menu menu,int orderNum,String dishName,int portion,int num){
            Record record=new Record();
            record.orderNum=orderNum;
            record.num=num;
            record.d= menu.searthDish(dishName);
            record.portion=portion;
            if((record.d!=null))
                record.getPrice=record.d.getPrice(portion)*num;
            return record;
        }
      public void delARecordByOrderNum(Order order,int orderNum){
                     order.records[orderNum-1].getPrice=0;
                     return ;
        }
      public int findRecordByNum(Order order,int orderNum,int j){
               for(int i=0;i<j;i++)
                   if(!(order.records[i].orderNum!=orderNum))
                    return 1;
                
                    return 0;
       }
    }

设计与分析:

这段代码是一个简单的点餐系统,程序需要进行用户输入和处理订单,并能够计算订单的总价格。整个程序可以分为三个类:Dish(菜品)、Menu(菜谱)和Order(订单记录)。

首先看到的是主函数Main,该函数包含了用户输入和订单处理的逻辑。通过Scanner类读取用户的输入,分解命令后根据具体操作调用Order和Menu的方法进行订单的添加、删除和查询。

其次是Dish类,用来表示每道菜品的名称和价格。其中getPrice()方法计算菜品的价格,考虑所选份额的不同而有不同的计算方法。

然后是Menu类,代表菜谱,由若干个Dish组成。可以使用addDish()方法将新菜品加入菜谱中,并且可以根据菜名查找菜品信息,返回Dish对象。

最后是Order类,用来保存所有订单记录。由Record数组来表示具体的一条订单记录。其中addaRecord()方法可以往订单记录中添加一条记录,delARecordByOrderNum()方法可以根据序号删除对应的订单记录,findRecordByNum()方法可以查找是否有特定序号的订单记录。并且通过getTotalPrice()方法计算所有订单记录的总价。

在整个程序中,类与类之间的关系十分清晰,便于程序的维护和拓展。同时通过Scanner类进行用户输入操作,方便实现交互式的点餐系统。

题目集3

7-1 菜单计价程序-3

源码:

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Dish[] dishes = {
                new Dish("西红柿炒蛋", 15),
                new Dish("清炒土豆丝", 12),
                new Dish("麻婆豆腐", 12),
                new Dish("油淋生菜", 9)
        };
        Menu menu = new Menu(dishes);
        Order order = new Order();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            String input = scanner.nextLine();
            if (input.equals("end")) {
                break;
            }
            String[] parts = input.split(" ");
            String dishName = parts[0];
            int portion = Integer.parseInt(parts[1]);
            Record record = order.addARecord(dishName, portion);
            /*if (record != null) {
                System.out.println(record.getPrice());
            }*/
        }
        System.out.println(order.getTotalPrice());
    }
}
class Dish {
    String name;
    int unit_price;

    public Dish(String name, int unit_price) {
        this.name = name;
        this.unit_price = unit_price;
    }

    public int getPrice(int portion) {
        double price = unit_price;
        if (portion == 2) {
            price *= 1.5;
        } else if (portion == 3) {
            price *= 2;
        }
        return (int) Math.round(price);
    }
}
class Menu {
    static Dish[] dishes;

    public Menu(Dish[] dishes) {
        this.dishes = dishes;
    }

    public static Dish searchDish(String dishName) {
        for (Dish dish : dishes) {
            if (dish.name.equals(dishName)) {
                return dish;
            }
        }
        return null;
    }
}
class Record {
    Dish dish;
    int portion;

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

    public int getPrice() {
        return dish.getPrice(portion);
    }
}
class Order {
    Record[] records;

    public Order() {
        records = new Record[0];
    }

    public int getTotalPrice() {
        int totalPrice = 0;
        for (Record record : records) {
            totalPrice += record.getPrice();
        }
        return totalPrice;
    }

    public Record addARecord(String dishName, int portion) {
        Dish dish = Menu.searchDish(dishName);
        if (dish == null) {
            System.out.println(dishName + " does not exist");
            return null;
        }
        Record record = new Record(dish, portion);
        records = Arrays.copyOf(records, records.length + 1);
        records[records.length - 1] = record;
        return record;
    }
}

设计与分析:

这道题目要求设计一个点菜计价程序,需要输入菜单和订单信息,并输出每桌的总价。具体的输入内容包括两部分:菜单、订单。其中,菜单由一条或多条菜品记录组成,每个菜品记录包含菜名和基础价格;订单由桌号标识、点菜记录和删除信息、代点菜信息构成。

在输入订单信息时,可以通过序号删除某个点菜记录,还可以添加代点菜信息。对于每桌点的所有菜品,根据不同份额(小、中、大)来计算价格。最后,根据点菜时间和营业折扣计算总价并输出。

为了实现这个程序,我们可以定义几个类来表示不同的对象:

1. Dish类:对应菜品上的一道菜的信息,包括菜名和基础价格,还有一个计算价格的方法。

2. Menu类:对应菜单上的所有菜品信息,可以根据菜名查找菜品,也可以添加新的菜品信息。

3. Record类:保存订单上的一道菜品记录,包括序号、菜品、份额等属性,并且有一个计算价格的方法。

4. Order类:保存用户点的所有菜品信息,包括多条记录和计算总价的方法等。

根据以上的类定义,我们就可以开始实现这个点菜计价程序了,具体可以按照以下流程:

1. 创建Menu对象,并初始化菜单信息,包括菜名和基础价格;

2. 创建Order对象,并对每张桌子的订单进行处理,包括添加订单记录、删除订单记录等操作;

3. 计算每张桌子的总价,考虑不同时间和营业折扣,并四舍五入保留整数。

最终输出每张桌子的总价即可。

心得:

因为时间关系,我并没有将代码补充完整,在我编写的代码里也存在着许多bug与没有完成的功能,但在之后的菜单计价系统作业中我会不断的完善代码,并向更深层次钻研。

7-2 有重复的数据

源码:

import java.util.HashSet;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        HashSet<Integer> set = new HashSet<>();
        boolean a = false;
        for (int i=0;i<n;i++) {
            int x=sc.nextInt();
            if (set.contains(x)) {/*set.contains(x)表示判断检查 HashSet 是否
                包含特定的元素 x。如果 HashSet 包含 x,则返回 true,否则返回 false*/
                a = true;
                break;
            }else{
            set.add(x);}//set.add(x)方法用于将元素x添加到 HashSet
        }
        if (a) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}

 

 设计与分析:

这段代码的主要功能是,在控制台输入一个整数n,接下来输入n个整数,判断是否有重复的数字出现。如果有,输出"YES";如果没有,输出"NO"。

首先,程序中使用了Scanner类和nextInt()方法从控制台读取输入。然后创建了一个HashSet集合对象set,用于存放输入的数字,HashSet集合可以有效地判断是否存在重复元素。

接着,通过循环语句对输入的n个整数进行遍历,每次添加到set中。当新添加的元素已经存在set中时,将a设为true,并跳出循环。

最后,根据变量a的值来输出结果。

需要注意的是,程序中使用了布尔类型的变量a来记录是否有重复元素,初值设为false。如果不加这个变量,即使找到了重复元素,因为无法跳出循环,程序也会输出"NO"。因此布尔类型变量a在此处起着关键的作用。

此外,尽管程序中没有涉及文件操作等I/O操作,但是却使用了Java的常见数据结构HashSet,值得学习借鉴。同时,程序使用了一些简单易懂的注释说明,增强了代码的可读性,也是好的编码实践之一。

7-3 去掉重复的数据
源码:
import java.util.HashSet;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        HashSet<Integer> set = new HashSet<>();
        boolean isFirst = false;
        for (int i=0;i<n;i++) {
            int x=sc.nextInt();
            if (!set.contains(x)) {/*set.contains(x)表示判断检查 HashSet 是否
                包含特定的元素 x。如果 HashSet 包含 x,则返回 true,否则返回 false*/
            set.add(x);//set.add(x)方法用于将元素x添加到 HashSet
                if(i<=0)
                System.out.print(x);
                else
                    System.out.print(" "+x);
        }
      }
   }
}

设计与分析:

这段代码与题目7-2类似,也是对输入的n个整数进行去重,并输出去重后的数字序列。

主要功能与之前分析的代码相似,不同之处在于此处使用了布尔类型的变量isFirst来记录是否是第一个输出的数字。变量初值设为false,当添加了新元素时,如果是第一个数字,则直接输出;否则在数字前面加上一个空格再输出。

此外,此程序省略了判断是否有重复元素的步骤,在执行set.add(x)时直接判断是否添加成功即可。但这种写法不能得到具体的判断结果,只能输出去重后的数字序列。

综上,这段代码实现了输入n个数字后去重并输出去重后的数字序列,同时使用了HashSet数据结构和一些简单易懂的流程控制语句,具备较好的可读性和实用性。

7-4 单词统计与排序

源码:

import java.util.*;
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String wenBen = sc.nextLine();
            String[] words = wenBen.split("[\\s,.]+");
            Set<String> uniqueWords = new HashSet<>(Arrays.asList(words));
            List<String> sortedWords = new ArrayList<>(uniqueWords);
            sortedWords.sort((a, b)->{
                if (a.length() != b.length()) {
                    return b.length()-a.length();
                } else {
                    return a.compareToIgnoreCase(b);
                }
            });
            for (String word : sortedWords) {
                System.out.println(word);
            }
        }
    }

设计与分析:

这段代码的主要功能是输入一行文本,将该文本中的单词按照长度和字典序进行排序,并去掉重复单词后输出。

首先,程序中使用Scanner类和nextLine()方法从控制台读取输入。然后使用split("[\\s,.]+")方法将文本拆分为单词数组words,其中"[\\s,.]+"表示用空格、逗号和句号作为分隔符,将文本按照空格、逗号和句号来分割成单词。

接着,通过创建HashSet集合对象uniqueWords将单词数组转化为不含重复元素的集合,实现去重操作。再使用ArrayList对象sortedWords将uniqueWords转化为列表,并使用Lambda表达式实现对字符串长度和字典序的排序。

最后,遍历列表输出排好序的单词即可。

此程序展现了Java 8中Lambda表达式和流的特性,能够使代码更简洁、易读,同时还使用了Set、List等常见数据结构和一些字符串处理方法,值得学习借鉴。

7-7 判断两个日期的先后,计算间隔天数、周数

 源码:
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;
    public class Main{
        public static void main(String[]args){
            Scanner sc = new Scanner(System.in);
            String date1String = sc.nextLine();
            String date2String = sc.nextLine();
            String[] date1Array = date1String.split("-");
            String[] date2Array = date2String.split("-");
            int y1 = Integer.parseInt(date1Array[0]);//将字符串转换成int
            int m1 = Integer.parseInt(date1Array[1]);
            int d1 = Integer.parseInt(date1Array[2]);
            int y2 = Integer.parseInt(date2Array[0]);
            int m2 = Integer.parseInt(date2Array[1]);
            int d2 = Integer.parseInt(date2Array[2]);
            LocalDate date1 = LocalDate.of(y1, m1, d1);//年月日初始化
            LocalDate date2 = LocalDate.of(y2, m2, d2);
            if (date1.isBefore(date2)) {
                System.out.println("第一个日期比第二个日期更早");
            } else if (date1.isAfter(date2)) {
                System.out.println("第一个日期比第二个日期更晚");
            }
            long daysBetween = ChronoUnit.DAYS.between(date1, date2);
            long weeksBetween = ChronoUnit.WEEKS.between(date1, date2);
                System.out.println("两个日期间隔"+Math.abs(daysBetween)+"天");
                System.out.print("两个日期间隔"+Math.abs(weeksBetween)+"周");
        }
    }

设计与分析:

这段代码的主要功能是输入两个日期,计算它们之间相差的天数和周数,并输出比较结果。

首先,程序中使用Scanner类和nextLine()方法从控制台读取输入。然后使用split("-")方法将输入的日期字符串拆分为年月日三个字符串,再使用parseInt()方法将它们转换为int型,以便于后面LocalDate对象的初始化和计算。

接着,通过LocalDate类对输入日期进行初始化,并使用isBefore()、isAfter()等方法来比较日期大小。

最后,通过使用ChronoUnit类中提供的常量DAYS和WEEKS,使用between()方法计算两个日期之间相差的天数和周数,并输出结果。

需要注意的是,此程序中使用了Java 8引入的新的日期和时间API,使得操作更加简单、方便。同时程序也使用了一些基本的字符串处理方法,如split()、parseInt()等,在实际编程和开发中十分常见和实用。

 
posted @ 2023-05-23 19:03  java的奴隶  阅读(35)  评论(0)    收藏  举报