类和对象常见题目详解

文章目录

  • 前言
  • 1. 求1+2+3+...+n
    • 解题思路
      • 思路一
      • 代码实现
      • 思路二
      • 代码实现
  • 2. 日期到天数转换
    • 解题思路
    • 代码实现
  • 3. 日期差值
    • 解题思路
    • 代码实现
  • 4. 打印日期
    • 解题思路
    • 代码实现
  • 5. 日期累加
    • 解题思路
    • 代码实现


前言

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

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

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

类和对象常见题目详解_第1张图片

解题思路

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

思路一

当一个对象被创建的时候,该对象会自动调用其默认构造函数,我们可以创建 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的结果
    }
};

思路二

我们还可以用前面学过的 内部类 来做这道题,把 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;

2. 日期到天数转换

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

类和对象常见题目详解_第2张图片

解题思路

举个例子,假设我们输入的是 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;
}

3. 日期差值

题目链接:KY111 日期差值

类和对象常见题目详解_第3张图片

解题思路

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

这道题输入的时候,是把年、月、日连在一起的,那么我们可以对输入的这 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;;
    }
}

4. 打印日期

题目链接:KY222 打印日期

类和对象常见题目详解_第4张图片

解题思路

把月份设置位从 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;
}

5. 日期累加

题目链接:KY258 日期累加

类和对象常见题目详解_第5张图片

解题思路

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

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

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

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

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

代码实现

#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); // 按照格式输出
    }
}

你可能感兴趣的:(深入C++世界,c++,算法,leetcode)