• C++类和对象(四)—— 类常见题目详解



    前言

    学完了类和对象我们来看看几道常见的习题!

    1. 求1+2+3+…+n

    题目链接:JZ64 求1+2+3+…+n

    在这里插入图片描述

    🍑 解题思路

    这里给出两种思路供大家参考。

    🍅 思路一

    当一个对象被创建的时候,该对象会自动调用其默认构造函数,我们可以创建 n 个类对象,这样就可以调用 n 次构造函数,模类似于递归实现;

    所以我们这里需要借助 静态成员变量,为什么呢?

    因为每个对象被创建时都有属于自己的普通成员变量,而静态成员变量是属于整个类的,这样才能使得这 n 次调用构造函数时自增的都是同一个变量,每个对象访问到的静态成员变量是同一个。

    同理,存储累加结果的变量也必须是静态成员变量。

    🍅 代码实现

    代码示例

    class Sum {
    public:
        Sum() {
            _ret += _i;
            _i++;
        }
        static int GetRet() {
            return _ret;
        }
    private:
        static int _ret; //存储累加的结果
        static int _i; //存储正在累加的数字
    };
    
    //静态成员变量的定义
    int Sum::_ret = 0;
    int Sum::_i = 1;
    
    class Solution {
    public:
        int Sum_Solution(int n) {
            Sum* p = new
            Sum[n]; //为n个Sum类对象申请空间(可调用n次构造函数)
    
            return Sum::GetRet(); //返回1+2+3+...+n的结果
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    🍅 思路二

    我们还可以用前面学过的 内部类 来做这道题,把 Sum 定义成 Solution 的内部类,也就是 Sum 是 Solution 的友元,那么在 Sum 类里面可以直接访问 Solution 的成员变量

    🍅 代码实现

    代码示例

    class Solution {
    private:
        class Sum
        {
        public:
            Sum()
            {
                _ret += _i;
                ++_i;
            }
        };
    public:
        int Sum_Solution(int n) {
            Sum* p = new Sum[n]; //为n个Sum类对象申请空间(可调用n次构造函数)
    
            return _ret; //返回1+2+3+...+n的结果
        }
    private:
        static int _i;
        static int _ret;
    };
    
    int Solution::_i = 1;
    int Solution::_ret = 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2. 日期到天数转换

    题目链接:HJ73 计算日期到天数转换

    在这里插入图片描述

    🍑 解题思路

    举个例子,假设我们输入的是 2022 10 20,那么我们肯定是要计算 10 月份之前的天数,也就是 1~9 月的天数,然后再加上 10 月的 20 天。

    注意:我们要定义一个函数,用来获取每月的天数(别忘了区分闰年和平年)

    🍑 代码实现

    代码示例

    #include 
    using namespace std;
    
    // 获取指定月份的天数
    int GetMonthDay(int year, int month) {
        int arrayDay[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
            return 29;
        } else {
            return arrayDay[month];
        }
    }
    
    int main() {
        int y, m, d; // 定义年月日
        int ret = 0;
        cin >> y >> m >> d;
    	
    	// 计算 1-(m-1) 的天数
        while (--m) { // m等于0时的退出循环
            ret = ret + GetMonthDay(y, m);
        }
        ret += d; // 还要加上m月的天数
        cout << ret << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3. 日期差值

    题目链接:KY111 日期差值

    在这里插入图片描述

    🍑 解题思路

    首先我们要找到输入的两个日期中,最大的日期和最小的日期。

    这道题输入的时候,是把年、月、日连在一起的,那么我们可以对输入的这 8 位数进行取模运算,就可以得到对应的年、月、日了。

    然后令日期不断加1天,直到第一个日期等于第二个日期为止。

    注意:我们要定义一个函数,用来获取每月的天数(别忘了区分闰年和平年)

    🍑 代码实现

    代码示例

    #include 
    using namespace std;
    
    // 获取指定月份的天数
    int GetMonthDay(int year, int month) {
        int arrayDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
            return 29;
        }
        else {
            return arrayDay[month];
        }
    }
    
    int main() {
        int t1, y1, m1, d1;
        int t2, y2, m2, d2;
        while (cin >> t1 >> t2) {
            // 默认t1 < t2
            int min = t1;
            int max = t2;
            while (max < min) {
                // 如果 t1 > t2,就交换
                min = t2;
                max = t1;
            }
            // 程序走到这里,一定是 min < max
            // 也就是 y1 < y2
            y1 = min / 10000;
            m1 = min % 10000 / 100;
            d1 = min % 100;
    
            y2 = max / 10000;
            m2 = max % 10000 / 100;
            d2 = max % 100;
    
            int ret = 1; // 初始化结果,相差天数
    
            // 循环的终止条件就是:y1=y2 && m1=m2 && d1=d2
            while (y1 < y2 || m1 < m2 || d1 < d2) { // 第一个日期不等于第二个日期时,就循环
                d1++; // 天数加一
                if (d1 == GetMonthDay(y1, m1) + 1) { // 满当月天数
                    ++m1; // 日期变为下个月的一号
                    d1 = 1;
                }
                if (m1 == 13) { // 月份满十二个月
                    ++y1; // 日期变为下一年的一月
                    m1 = 1;
                }
                ++ret; // 相差天数+1
            }
            cout << ret << endl;;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    4. 打印日期

    题目链接:KY222 打印日期

    在这里插入图片描述

    🍑 解题思路

    把月份设置位从 1 月开始,判断所给总天数是否大于该年该月的总天数:

    若大于,则将总天数减去该月的总天数后作为新的总天数,然后将月份加 1,继续进行判断;

    若小于,则结束判断,输出日期即可。

    注意:我们要定义一个函数,用来获取每月的天数(别忘了区分闰年和平年)

    🍑 代码实现

    代码示例

    #include 
    using namespace std;
    
    // 获取指定月份的天数
    int GetMonthDay(int year, int month) {
        int arrayDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
            return 29;
        }
        else {
            return arrayDay[month];
        }
    }
    
    int main() {
        int y, m, d;
        while (cin >> y >> d) {
            m = 1; // 从1月开始
            while (d > GetMonthDay(y, m)) {
                d -= GetMonthDay(y, m);
                m++;
            }
            printf("%d-%02d-%02d\n", y, m, d); //按格式输出
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    5. 日期累加

    题目链接:KY258 日期累加

    在这里插入图片描述

    🍑 解题思路

    这道题就和日期类这篇文章中的,日期 + 天数 的实现是一样的。

    我们先将需要累加的天数加到 “日” 上,然后通过不断的迭代使得日期合法,迭代过程如下:

    判断 “日” 是否大于该年该月的总天数,若大于,则将 “日” 减去该月的总天数后作为新的 “日” ,然后将月份加一,继续进行判断;

    若小于,则结束判断,输出日期即可。

    注意:每次月份加一后需要判断 “年” 是否需要进位,若需要进位还需判断进位后的年是否为闰年。

    🍑 代码实现

    #include 
    using namespace std;
    
    // 获取指定月份的天数
    int GetMonthDay(int year, int month) {
        int arrayDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
            return 29;
        }
        else {
            return arrayDay[month];
        }
    }
    
    // 日期 + 天数
    int main() {
        int m, year, month, day, n;
        cin >> m;
        // 控制样例的个数
        for (int i = 0; i < m; ++i) {
            cin >> year >> month >> day >> n; // 读取年、月、日和需要累加的天数
            day += n; // 先将需要累加的天数加到“日”上
            while (day > GetMonthDay(year, month)) { // 若此时"日"大于当天的天数,那么就进入循环
                day -= GetMonthDay(year, month); // 从"日"里面减去当月的天数
                month++; // 月份加1
                if (month == 13) { // 判断月份是否大于12
                    ++year;
                    month = 1;
                }
            }
            printf("%d-%02d-%02d\n", year, month, day); // 按照格式输出
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    Go基础语法:list
    TsingHua:FPT: Improving Prompt Tuning Efficiency via Progressive Training
    opnet物联网仿真2.5 陈敏 包交换网络全解----修正版
    Linux环境MySQL数据库主从复制保姆级教程
    ChatGPT 学习笔记 - 1
    IO/多路复用(select/poll/epoll)
    [软件安装] tmux安装及相关事项
    二分查找 【模板+中间值问题】
    Python+大数据-知行教育(五)-意向用户主题看板_增量流程
    每日一题 322零钱兑换(完全背包)(灵神版本)
  • 原文地址:https://blog.csdn.net/m0_63325890/article/details/127416116