每日一刷——1.20——准备蓝桥杯

链接:登录---专业IT笔试面试备考平台_牛客网

来源:牛客网

题目一

请统计某个给定范围[L, R]的所有整数中,数字2出现的次数。

比如给定范围[2, 22],数字2在数2中出现了1次,在数12中出现1次,在数20中出现1次,在数21中出现1次,在数22中出现2次,所以数字2在该范围内一共出现了6次。

输入描述:

复制代码
输入共1行,为两个正整数L和R,之间用一个空格隔开。

输出描述:

复制代码
输出共1行,表示数字2出现的次数。

示例1

输入

2 22

输出

6

示例2

输入

2 100

输出

20

Java代码展示:

java 复制代码
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        int a=0,b=0,num=0;
        Scanner in =new Scanner(System.in);
        //这个是循环读取
        a =in.nextInt();
        b =in.nextInt();
        for(int i=a;i<=b;i++){
            int temp =i;
            while(temp!=0){
                int j=temp%10;
                if(j==2){
                    num++;
                }
                temp/=10;
            }
        }
        System.out.println(num);
    }
}

注意:

在 Java 中,变量 ifor 循环的迭代变量,它在循环的每次迭代中都会被更新。如果在 while 循环中直接使用 i 而不创建 temp 变量,会出现以下问题:

当我们在 while 循环中修改 i 的值(通过 temp /= 10),这会影响 for 循环的迭代过程。因为 i 不仅是 while 循环的控制变量,也是 for 循环的迭代变量,修改 i 会导致 for 循环的迭代逻辑出现错误。

例如,假设 i 的初始值是 123,在 while 循环中你将 i 不断除以 10 来检查其每一位数字是否为 2。第一次 while 循环结束后,i 的值就变成了 12,而不是 for 循环期望的下一个迭代值 124。这会导致 for 循环的迭代顺序被破坏,最终结果错误。

为了避免这种情况,我们应该引入了 temp 变量,将 i 的值复制给 temp,然后在 while 循环中对 temp 进行操作,这样就不会影响 for 循环的迭代过程。

题目二

题目描述:B-日历中的数字_牛客竞赛语法入门班函数与递归习题

只通过了测试样例的代码。。。

java 复制代码
// 日中包含的   月中包含的   年中包含的

// 数字x在这个月的日期里出现了多少次。

//闰年
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        
        Scanner in =new Scanner(System.in);
        while(in.hasNextInt()){
            int count=0;
            int q=0;
        int year =in.nextInt();
        int month =in.nextInt();
        int num =in.nextInt();
        
        while(year!=0){
            if(year%10 ==num){
                q++;
            }
            year/=10;
        }
        int[] date={31,28,31,30,31,30,31,31,30,31,30,31};
        count+=q*date[month-1];
        int temp1=month;
        while(temp1!=0){
            if(temp1%10==num){
                if(temp1==2){
                    count+=date[month-1];
                    //判断闰年代码
                    if((year % 4 == 0 && year % 100!= 0) || year % 400 == 0){
                        count+=1;
                    }
                }else{
                    count+=date[month-1];
                }
            }
            temp1/=10;
        }
        
        for(int i=1;i<=date[month-1];i++){
            int temp=i;
            while(temp!=0){
                if(temp%10==num){
                    count++;
                }
                temp/=10;
            }
        }
        
        if(num==0){
            count+=9;
            if(month<10){
                count+=date[month-1];
            }
        }
        
        System.out.println(count);
        }
    }
}

正确代码展示:

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 创建一个 Scanner 对象,用于从标准输入读取数据
        Scanner sc = new Scanner(System.in);
        // 定义一个数组 arr 存储每个月的天数,2 月初始化为 28 天
        int[] arr = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        // 进入一个循环,只要输入流还有数据,就会一直执行
        while (sc.hasNext()) {
            // 创建一个 StringBuilder 对象,用于存储日期字符串
            StringBuilder sb = new StringBuilder();
            // 从输入读取年份 y
            int y = sc.nextInt();
            // 从输入读取月份 m
            int m = sc.nextInt();
            // 从输入读取一个字符 x
            char x = sc.next().charAt(0);
            // 判断是否为闰年,如果是闰年将 2 月的天数修改为 29 天,否则为 28 天
            if (y % 400 == 0 || (y % 4 == 0 && y % 100!= 0)) {
                arr[1] = 29;
            } else {
                arr[1] = 28;
            }
            // 循环遍历该月的每一天
            for (int i = 1; i <= arr[m - 1]; i++) {
                // 使用 String.format 方法将年份、月份和日期组合成一个字符串,格式为 yyyymmdd
                // %04d 表示年份为 4 位数字,不足 4 位在前面补 0
                // %02d 表示月份和日期为 2 位数字,不足 2 位在前面补 0
                String date = String.format("%04d%02d%02d", y, m, i);
                // 将生成的日期字符串添加到 StringBuilder 中
                sb.append(date);
            }
            // 计数器,用于统计字符 x 出现的次数
            int count = 0;
            // 遍历 StringBuilder 中的每个字符
            for (int i = 0; i < sb.length(); i++) {
                // 如果字符等于输入的字符 x,计数器加 1
                if (sb.charAt(i) == x) {
                    count++;
                }
            }
            // 输出字符 x 在所有日期字符串中出现的次数
            System.out.println(count);
        }
    }
}

代码实现逻辑分析:

导入包和类的定义

  • import java.util.Scanner;:导入 Scanner 类,用于从标准输入读取数据。

  • public class Main:定义一个名为 Main 的公共类。

  • public static void main(String[] args):程序的入口点。

变量和对象的初始化

  • Scanner sc = new Scanner(System.in);:创建一个 Scanner 对象,用于读取用户输入。

  • int[] arr = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};:存储每个月的天数,初始时 2 月为 28 天。

输入处理和闰年判断

  • while (sc.hasNext()):只要输入流还有数据,就会执行以下操作。

  • StringBuilder sb = new StringBuilder();:创建一个 StringBuilder 对象,用于存储组合的日期字符串。

  • int y = sc.nextInt();:从输入读取年份。

  • int m = sc.nextInt();:从输入读取月份。

  • char x = sc.next().charAt(0);:从输入读取一个字符。

  • 对输入的年份 y 进行闰年判断,如果是闰年(能被 400 整除或能被 4 整除但不能被 100 整除),将 arr[1](2 月的天数)设置为 29 天,否则为 28 天。

日期字符串的生成和存储

  • for (int i = 1; i <= arr[m - 1]; i++):遍历该月的每一天。

  • String date = String.format("%04d%02d%02d", y, m, i);:将年份、月份和日期格式化为 yyyymmdd 的字符串。

  • sb.append(date);:将生成的日期字符串添加到 StringBuilder 中。

字符计数

  • int count = 0;:初始化一个计数器,用于统计字符 x 的出现次数。

  • for (int i = 0; i < sb.length(); i++):遍历 StringBuilder 中的字符。

  • if (sb.charAt(i) == x):如果字符等于输入的字符 x,计数器加 1。

结果输出

  • System.out.println(count);:输出字符 x 在存储的日期字符串中出现的次数。

使用说明:

  • 运行程序后,程序会不断等待用户输入。

  • 每次输入的格式应该是:年份 月份 字符,例如 2024 2 a

  • 程序会将输入的年份、月份和该月的日期按照 yyyymmdd 的格式组合成一个字符串,存储在 StringBuilder 中。

  • 程序会根据输入的年份判断是否为闰年,并更新 2 月的天数。

  • 最后程序会统计输入的字符在存储的日期字符串中出现的次数并输出结果。

这个程序的主要目的是统计用户输入的字符在该年该月的日期字符串中出现的次数。例如,输入 2024 2 a,程序会将 2024 年 2 月的日期 2024020120240229 组合成一个字符串,然后统计字符 a 在这个字符串中出现的次数。

错误原因分析 :

就是感觉自己写代码并没有利用到计算机的精髓,甚至认为计算机实现比大脑自己想还要复杂,就感觉怪怪的,自己写一堆代码,麻烦的判断是不是闰年,如果年有这个数字怎么办?月有这个数字怎么办?就感觉计算机并没有帮到任何忙,只是把我的人脑思考的思路实现了。

知识点对应函数的学习:

sc.next().charAt(0)
  • sc.next() 用于读取输入的下一个字符串,而 charAt(0)String 类的方法,用于获取该字符串的第一个字符。例如,char x = sc.next().charAt(0); 这一行先读取一个字符串,然后取其第一个字符存储在 x 中。

String.format()
  • 这是 String 类的一个静态方法,用于格式化字符串。在代码中 String date = String.format("%04d%02d%02d", y, m, i); 它将 y(年份)、m(月份)和 i(日期)按照 %04d%02d%02d 的格式组合成一个新的字符串。%04d 表示将整数格式化为 4 位数字,不足 4 位在前面补零,%02d 表示将整数格式化为 2 位数字,不足 2 位在前面补零

StringBuilder用法
一、创建 StringBuilder 对象
java 复制代码
StringBuilder sb = new StringBuilder();

上述代码创建了一个空的 StringBuilder 对象。StringBuilder 类提供了一种可变的字符串序列,允许对字符串进行动态操作,与 String 类不同,String 对象是不可变的,一旦创建,其内容不能修改,而 StringBuilder 可以在原有的基础上添加、插入、删除和替换字符。

二、添加内容到 StringBuilder

1、append() 方法:

java 复制代码
sb.append("Hello");
sb.append(" ");
sb.append("World");

这个方法可以将各种数据类型(如 Stringcharintdouble 等)添加到 StringBuilder 对象的末尾。在我的代码中:

java 复制代码
for (int i = 1; i <= arr[m - 1]; i++) {
    String date = String.format("%04d%02d%02d", y, m, i);
    sb.append(date);
}

通过 append 方法将格式化后的日期字符串添加到 sb 中,最终形成一个包含该月所有日期的长字符串。

三、插入内容到 StringBuilder

1、insert() 方法:

java 复制代码
sb.insert(5, " there");

此方法可以在 StringBuilder 的指定位置插入内容。例如,上述代码将在索引为 5 的位置插入 " there",如果 sb 原本存储 "Hello World",操作后会变成 "Hello there World"

四、删除内容

1、delete() 方法:

java 复制代码
sb.delete(5, 11);

这个方法可以删除 StringBuilder 中从起始索引到结束索引(不包括结束索引)的字符。例如,在上述插入操作后,使用 delete 方法会将 " there" 删除,sb 会变回 "Hello World"

2、deleteCharAt() 方法:

java 复制代码
sb.deleteCharAt(5);

该方法会删除 StringBuilder 中指定索引处的字符。

五、替换内容

1、replace() 方法:

​​

java 复制代码
sb.replace(0, 5, "Hi");

此方法将从起始索引到结束索引(不包括结束索引)的内容替换为新的字符串。上述代码将把 "Hello" 替换为 "Hi",如果 sb 存储 "Hello World",操作后会变成 "Hi World"

六、反转 StringBuilder 内容

reverse() 方法:

java 复制代码
sb.reverse();

该方法会将 StringBuilder 中的字符序列进行反转。例如,如果 sb 存储 "Hello World",操作后会变成 "dlroW olleH"

七、转换为 String

toString() 方法:

java 复制代码
String result = sb.toString();

这个方法将 StringBuilder 的内容转换为 String 类型,在需要将 StringBuilder 的内容作为字符串使用时,通常使用这个方法。

八、其他有用的方法

1、length() 方法:

java 复制代码
int len = sb.length();

​​ 该方法返回 StringBuilder 中字符序列的长度。

2、charAt() 方法:

java 复制代码
char c = sb.charAt(0);

此方法返回 StringBuilder 中指定索引处的字符。

在原代码中,使用 StringBuilder 的目的是将一个月的所有日期按照 yyyymmdd 的格式拼接成一个长字符串,以便后续统计某个字符的出现次数。通过循环将日期添加到 StringBuilder 中,避免了多次字符串拼接造成的性能开销(因为每次使用 String 拼接都会创建新的 String 对象,而 StringBuilder 只在原对象上操作)。

java 复制代码
import java.util.Scanner;

public class StringBuilderExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        // 添加字符串
        sb.append("I");
        sb.append(" love");
        sb.append(" Java");
        // 插入字符串
        sb.insert(2, " really ");
        // 删除字符串
        sb.delete(2, 9);
        // 替换字符串
        sb.replace(0, 1, "We");
        // 反转字符串
        sb.reverse();
        // 输出最终结果
        System.out.println(sb.toString());
    }
}

在上述示例中,我们展示了 StringBuilder 的多种操作。首先添加 "I love Java",然后在索引 2 处插入 " really ",再删除 " really ",接着将 "I" 替换为 "We",最后将整个字符串反转。

使用 StringBuilder 可以提高字符串操作的效率,特别是在需要频繁修改字符串内容的情况下,避免了 String 的不可变特性带来的性能问题。同时,StringBuilder 提供了丰富的方法,可以方便地对字符串进行各种修改和操作。

相关推荐
爱倒腾的老唐3 分钟前
01、如何学习单片机
单片机·嵌入式硬件·学习
.格子衫.5 小时前
Spring Boot 原理篇
java·spring boot·后端
多云几多5 小时前
Yudao单体项目 springboot Admin安全验证开启
java·spring boot·spring·springbootadmin
于小汐在咯6 小时前
词根学习笔记 | Agri系列
笔记·学习
Swift社区6 小时前
LeetCode 394. 字符串解码(Decode String)
算法·leetcode·职场和发展
霜绛6 小时前
Unity:Json笔记——Json文件格式、JsonUtlity序列化和反序列化
学习·unity·json·游戏引擎
tt5555555555557 小时前
LeetCode进阶算法题解详解
算法·leetcode·职场和发展
让我们一起加油好吗7 小时前
【基础算法】DFS中的剪枝与优化
算法·深度优先·剪枝
Jabes.yang7 小时前
Java求职面试实战:从Spring Boot到微服务架构的技术探讨
java·数据库·spring boot·微服务·面试·消息队列·互联网大厂
聪明的笨猪猪7 小时前
Java Redis “高可用 — 主从复制”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试