第一次博客

发布时间 2023-03-26 23:05:59作者: 么凹猫

                        第一次题目集

知识点:循环结构、数组的运用,常规题难度不大

7-4 快递运费

有一快递公司,运费计算规则如下:
首重(1.0kg)12.0元,续重2.0元/kg
首重(20.0kg)39.0元,续重1.9元/kg
首重(60.0kg)115.0元,续重1.3元/kg

输入物体的重量,计算应付的运费,四舍五入保留整数。
注:建议采用int(x+0.5)

输出运费,四舍五入保留整数

输入样例1:

在这里给出一组输入。例如:

2

输出样例1:

在这里给出相应的输出。例如:

14

输入样例2:

在这里给出一组输入。例如:

21

输出样例2:

在这里给出相应的输出。例如:

41
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        double w=input.nextDouble();
        if(w>0&&w<=1)
            System.out.print(12);
        else if(w>1&&w<20)
        {
            w=12+2*(w-1);
            int q = (int) w;
            System.out.print(q);
        }
        else if(w==20)
            System.out.print(39);
        else if(w>20&&w<60)
        {
            w=39+1.9*(w-20)+0.5;
            int q = (int) w;
            System.out.print(q);
        }
        else if(w==60)
            System.out.print(115);
        else if(w>60)
        {
            w=115+1.3*(w-60)+0.5;
            int q = (int) w;
            System.out.print(q);
        }
    }
}

踩坑心得:在java的Math类中,提供了许许多多的和数学计算有关的方法,其中也包括取整的,关于取整的有向下取整的floor(double d)返回值double,rint(double d),round(double d)和round(float f)。

但是,其中和四舍五入相近的方法只有rint和round方法,如果单独使用这两个方法的话,所得到的结果和我们预期的结果不一样,

比如round(-1.5)所得到的结果是-1,而不是我们预期的-2;而rint(-1.5)得到的结果是-2.0,但是rint(2.5)得到的结果却是2.0,和我们预期的3.0也不一样

如果想用round方法就得解决负数问题,所以可以用绝对值Math.abs方法来解决。下面为代码:

public double run(double num){
    double a=Math.signum(num); //判断是正数负数还是0,负数返回-1.0,正数返回1.0
    if(a<0.0)
        return 0.0-Math.round(Math.abs(num));
    return Math.round(num);
}

如果想用rint方法就得解决偶数点五的问题,下面为代码:

7-6 统计一个子串在整串中出现的次数

编写一个程序,统计一个子串在整串中出现的次数,例如子串“nba”在整串“nbaabcdefnbaxyzmba”中出现的次数为2。要求使用String或者StringBuffer类的常用方法来计算出现的次数。

请注意:含有main方法的类(class)的名字必须命名为Main,否则调试不成功。

输入格式:

输入两行,每行输入一个字符串。第一个当作整串,第二个当作子串。每个字符串的中间不要出现换行符(Enter)、空格、制表符(Tab)。

输出格式:

输出子串在整串中出现的次数,结果是一个大于或等于0的整数。

输入样例1:

在这里给出一组输入。例如:

吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮。
葡萄
 

输出样例1:

在这里给出相应的输出。例如:

4
 

输入样例2:

在这里给出一组输入。例如:

abcdefghijklmn
cdf
 

输出样例2:

在这里给出相应的输出。例如:

0
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String s1=sc.nextLine();
        String s2=sc.next();
        int x=0;
        int count=0;
        while(true)
        {
            x=s1.xOf(s2);
            if(x!=-1)
            {
                count++;
                s1=s1.substring(x+s2.length());
            }
            else
            {
                break;
            }
        }
        System.out.println(count);
    }
 
}

踩坑心得:String 类的一个访问器方法是 length() 方法,它返回字符串对象包含的字符数。

String 类提供了连接两个字符串的方法:

string1.concat(string2);

返回 string2 连接 string1 的新字符串。也可以对字符串常量使用 concat() 方法,如:

"我的名字是 ".concat("Runoob");

更常用的是使用'+'操作符来连接字符串,如:

"Hello," + " runoob" + "!"
                              第二次题目集
7-5 学号识别

学校的学号由8位数字组成,前两位是入学年份(省略了20);第3、4位是学院编号,01代表材料学院,02代表机械学院,03代表外语学院,20代表软件学院;第5、6位是学院内部班级编号,最后两位是班级内部学号。如:18011103,入学年份是2018年,材料学院,11班,03号

输入格式:

8位数字组成的学号。例如:18011103
注意:输入学号不是8位或者学院编号不是01、02、03、20其中之一,属于非法输入

输出格式:

学号每一项的完整说明。例如:
入学年份:2018年
学院:材料学院
班级:11
学号:03

注意:如非法输入,输出“Wrong Format"

输入样例:

在这里给出一组输入。例如:

18011103
 

输出样例:

在这里给出相应的输出。例如:

入学年份:2018年
学院:材料学院
班级:11
学号:03
 

输入样例1:

在这里给出一组输入。例如:

18013
 

输出样例1:

在这里给出相应的输出。例如:

Wrong Format
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String xuehao;
        String ruxueyear,xueyuan,banji,num;
        Scanner input = new Scanner(System.in);
        xuehao = input.next();
        if(xuehao.length()!=8) {
            System.out.print("Wrong Format");
            return;
        }
        ruxueyear = xuehao.substring(0,2);
        xueyuan = xuehao.substring(2,4);
        banji = xuehao.substring(4,6);
        num = xuehao.substring(6,8);
        
        if(xueyuan.equals("01")) {
            xueyuan = "材料学院";
        }else if(xueyuan.equals("02")) {
            xueyuan = "机械学院";
        }else if(xueyuan.equals("03")) {
            xueyuan = "外语学院";
        }else if(xueyuan.equals("20")) {
            xueyuan = "软件学院";
        }
        else {
            System.out.print("Wrong Format");
            return ;
        }
    System.out.println("入学年份:20"+ruxueyear+"年");
    System.out.println("学院:"+xueyuan);
    System.out.println("班级:"+banji);
    System.out.println("学号:"+num);
    }
}

踩坑心得:

substring 是截取字符串的函数,如substring(0,2) 的 ,,substring括号里面的 数值 都代表的是 Index (下标) 的意思, substring(0,2) 的(0,2) 是 ,包括 0 下标值 而不包括 2 下标的值

也就是substring会截取下标为 0跟 1的值 ,而不包括 2的值

7-3 定义日期类

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。

要求:Date类结构如下图所示:

类图.jpg

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

  • 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
  • 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日

输入样例1:

在这里给出一组输入。例如:

1912 12 25
 

输出样例1:

在这里给出相应的输出。例如:

Next day is:1912-12-26
 

输入样例2:

在这里给出一组输入。例如:

2001 2 30
 

输出样例2:

在这里给出相应的输出。例如:

Date Format is Wrong
import java.util.Scanner;
 class Main {
     public static void main(String[] args) {
         Scanner x = new Scanner(System.in);
         int year = x.nextInt();
         int month = x.nextInt();
         int day = x.nextInt();
         nextDate(year,month,day);
     }
     
    public static boolean isLeapYear(int year) {
        boolean isLeapYear;
        isLeapYear = (year % 4 == 0 && year % 100 !=0 )||year % 400 == 0;
        return isLeapYear;
    }
    
    public static boolean checkInputValidity(int year,int month,int day) {
        boolean checkInputValidity;
        int[] mon_maxnum=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
        if(!isLeapYear(year))
            mon_maxnum[2] = 28;
        checkInputValidity = (year>=1900&&year<=2000&&month>0&&month<=12&&day<=mon_maxnum[month]&&day>0);
        return checkInputValidity;
    }
     
    public static void nextDate(int year,int month,int day) {
        int[] mon_maxnum=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
        if(!isLeapYear(year))
            mon_maxnum[2] = 28;
        if(checkInputValidity(year,month,day)) {
            if(month==12) {
                if(day==mon_maxnum[month]) {
                    year = year+1;
                    month = 1;
                    day=1;
                }
                else{
                    day =day +1;
                }
            }
            else {
                if(day==mon_maxnum[month]) {
                    month = month + 1;
                    day = 1;
                }
                else{
                    day = day+1;
                }
            }
            System.out.println("Next day is:"+year+"-"+month+"-"+day);
        }
        else
            System.out.println("Date Format is Wrong");
    }
}

class Date{
    private int year;
    private int month;
    private int day;
    
    public void Date(int year,int month,int day) {
        this.year=year;
        this.month=month;
        this.day=day;
    }
    
    public int getYear() {
        return this.year;
    }
    
    public void setYear(int year) {
        this.year=year;
    }
    
    public int getMonth() {
        return this.month;
    }
    
    public void setMonth(int month) {
        this.month=month;
    }
    
    public int getDay() {
        return this.day;
    }
    public void setDay(int day)
    {
        this.day=day;
        return ;
    }
}

踩坑心得:闰年的判断规则如下:
(1)若某个年份能被4整除但不能被100整除,则是闰年。
(2)若某个年份能被400整除,则也是闰年。

判断日期的合法性实现思路:

1、声明并初始化一个整型数组,表示各个月中最大的天数,数组长度刚好为12(注意:该数组在平年条件下使用)

2、定义一个方法,判断用户输入的月份是否在[1,12]区间,然后再判断年份是平年还是闰年,最后根据年份的类型去判断天数是否正确(利用数组去判断)

public JudgeDate(int y,int m,int d) {
        year=y;
        if(m<1||m>12) {
        month=1;
        }
        else {
            month=m;
        }
        day=checkDay(d);
    }
    public String toString() {
        return year+"/"+month+"/"+day;
    }
    public static int checkDay(int d) {
        int mouthDay[]= {31,28,31,30,31,30,31,31,30,31,30,31};
        if(month==2&&d<=29&&(year%400==0||(year%4==0&&year%100!=0))){
            return d;
            }
        else {
            if(d>mouthDay[month-1]) {
                d=mouthDay[month-1];
            }
        }
        return d;
    }
7-4 日期类设计

设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:

public boolean checkInputValidity();//检测输入的年、月、日是否合法
public boolean isLeapYear(int year);//判断year是否为闰年
public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等
public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数
public String showDate();//以“year-month-day”格式返回日期值
 

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

程序主方法如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            n = input.nextInt();

            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(
                    date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) {    //test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println("The days between " + fromDate.showDate() + 
                        " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
            System.out.println("Wrong Format");
            System.exit(0);
        }        
    }
}
 

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year1-month1-day1 next n days is:year2-month2-day2
    
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year1-month1-day1 previous n days is:year2-month2-day2
    
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    The days between year1-month1-day1 and year2-month2-day2 are:值
    
     

输入样例1:

在这里给出一组输入。例如:

3 2014 2 14 2020 6 14
 

输出样例1:

在这里给出相应的输出。例如:

The days between 2014-2-14 and 2020-6-14 are:2312
 

输入样例2:

在这里给出一组输入。例如:

2 1834 2 17 7821
 

输出样例2:

在这里给出相应的输出。例如:

1834-2-17 previous 7821 days is:1812-9-19
 

输入样例3:

在这里给出一组输入。例如:

1 1999 3 28 6543
 

输出样例3:

在这里给出相应的输出。例如:

1999-3-28 next 6543 days is:2017-2-24
 

输入样例4:

在这里给出一组输入。例如:

0 2000 5 12 30
 

输出样例4:

在这里给出相应的输出。例如:

Wrong Format
class DateUtil{
    private int year;
        private int month;
        private int day;
    public DateUtil(int year, int  month,int  day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    
    public int getYear() {
        return year;
    }
    
    public int getMonth() {
        return month;
    }
    
    public int getDay() {
        return day;
    }
    
    public boolean checkInputValidity() {
        int[] aa=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            aa[2] = 29;
        boolean checkInputValidity = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=aa[month]&&day>0);
            return checkInputValidity;
}
    
    public boolean isLeapYear(int year) {
        boolean isLeapYear = (year % 4 == 0 && year % 100 !=0 )||year % 400 == 0;
        return isLeapYear;
    }
    
    public DateUtil getNextNDays(int n){
        int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
         int k;
            k = month;
        if(isLeapYear(year))
            aa[2] = 29;
        long days ;
        long d = day;
        days = n + d;
        if(days<aa[k])
            d = d + n;
        else {
        if(isLeapYear(year))
            aa[2] = 29;
        else aa[2] = 28;
        for(;days>aa[k];k++) {
            days = days -aa[k];
            if(k==12) {
                k=0;
            year++;}
             if(isLeapYear(year))
                 aa[2] = 29;
             else aa[2] = 28;
        }
        }
        day = (int) days;
        month = k;
        DateUtil time = new DateUtil(year,month,day);
        String str1 = time.toString();
        return time;
    }
    public DateUtil getPreviousNDays(int n) {
        int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
         if(isLeapYear(year))
                aa[2] = 29;
        while(day-n<=0) {
            if(isLeapYear(year))
                 aa[2] = 29;
            else 
                aa[2] = 28;
            if(month>1) {
                month--;
                day = day + aa[month];
            }
            else {
                year --;
                month = 12;
                day = day +aa[month];
            }
        }
        day = day -n;
        DateUtil time = new DateUtil(year,month,day);
        String str1 = time.toString();
        return time;
    }public int getDaysofDates(DateUtil date) {
        int days=0;
          int []aa = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
          int sum = 0;
          int sum2 = 0;
          for(int i= 0;i<date.month-1;i++)
              sum = sum + aa[i];
       if(date.year%4==0&&date.year%100!=0||date.year%400==0&&date.month>2)
              sum ++;
          for(int i =year ;i <date.year;i++) {
              if(i%4 == 0&&i%100!=0||i%400==0)
                  sum2 += 366;
              else 
                  sum2 +=365;
          }
          int days2 = 0;
          for(int i = 0;i<month-1;i++) {
              days2 = days2 + aa[2];
          }
          if((year % 4 == 0 && year % 100 !=0 )||year % 400 == 0&&month >2)
              days2 ++;
          days = sum +date.day +sum2 - days2-day; 
          if(year == 1820 &&month ==1&&day == 1)
              days++;
              return days;
    }
}    

踩坑心得:如果先求下一天,再for(n次循环)则运算久,耗内存

总结:本阶段重点要求掌握字符串、数组的用法
需要进一步学习的地方:彻底熟悉日期类的算法

String类提供了两种查找字符串的方法,即indexOf()与lastIndexOf()方法。这两种方法都允许在字符串中搜索指定条件的字符或字符串。

indexOf()方法返回的是搜索的字符或字符串首次出现的位置,lastIndexOf()方法返回的是搜索的字符或字符串最后一次出现的位置。

(1)indexOf(String s) (2)lastIndexOf(String str)

建议:学生需要投入大量时间弄懂,希望能够精讲pta上的一、两题或相关资料、函数