【C++之类和对象】日期类的实现

news2025/2/24 23:11:47

目录

    • 前言
    • 一、日期类的基本样式
    • 二、构造函数
    • 三、拷贝构造函数
    • 四、赋值运算符重载
    • 五、日期比较
        • 1. 判断一个日期是否小于另一个日期
        • 2. 判断一个日期和另一个日期是否相等
        • 3. 判断一个日期是否小于等于另一个日期
        • 4. 判断一个日期是否大于另一个日期
        • 5. 判断一个日期是否大于等于另一个日期
    • 六、日期+天数 = 天数后的日期
    • 七、日期+=天数 = 天数后的日期
    • 八、日期-天数 = 天数前的日期
    • 九、日期-=天数 = 天数前的日期
    • 十、日期的++ = 日期
        • 1. 前置++
        • 2. 后置++
    • 十一、日期的-- = 日期
        • 1. 前置--
        • 2. 后置--
    • 十二、日期-日期 = 相差天数
    • 十三、日期的流插入和流提取运算
        • 1、日期的流插入
        • 2. 日期的流提取
    • 十四、打印日期

前言

在我们的日常生活中都需要知道当天的日期,同时也可能需要知道几天后的日期,几天前的日期,还有就是距离我们想要的日期还剩几天,比如:距离高考还有几天这样的信息,所以日期类对于我们任何人来说都是一个非常重要的工具。今天这篇文章将详细介绍日期类中各种功能的实现以及细节。

首先需要建一个日期类的项目来实现我们日期类中的全部代码
在这里插入图片描述

一、日期类的基本样式

我们实现的日期类中主要包含的成员变量属性有:年、月、日,并且其中可能包含各种功能(函数):构造函数,打印日期,拷贝构造函数,赋值运算符重载函数,其他的运算符重载函数。具体下面代码基于说明:

  • 头文件中的代码
// 头文件的包含和命名空间的展开
#include <iostream>
using std::endl;
using std::cout;
using std::cin;

class Date
{
public:
	// 头文件中需要包含函数的声明:

	// 判断闰年
	bool isLeapYear(int year)  const;

	// 求每个月的天数
	int GetMonthDay(int year, int month)  const;

	// 构造函数
	Date(int year = 1, int month = 1, int day = 1);

	// 拷贝构造函数
	Date(const Date& d);

	// 赋值运算符重载
	Date& operator=(const Date& d);

	// 比较日期
	bool operator<(const Date& d)  const;

	bool operator<=(const Date& d)  const;

	bool operator==(const Date& d)  const;

	bool operator>(const Date& d)  const;

	bool operator>=(const Date& d)  const;


	// 日期+天数 = 日期
	Date operator+(int day)  const;

	// 日期+=天数 = 日期
	Date& operator+=(int day);

	// 日期-天数 = 日期
	Date operator-(int day)  const;

	// 日期-=天数 = 日期
	Date& operator-=(int day);

	// 日期++ = 日期
	// 前置++
	Date& operator++();

	// 后置++
	Date operator++(int);

	// 日期-- = 日期
	// 前置--
	Date& operator--();

	// 后置--
	Date operator--(int);

	// 日期-日期 = 相差天数
	int operator-(const Date& d)  const;

	// 打印日期
	void Print()const;

		// 使用流插入将日期进行输出
	friend std::ostream& operator<<(std::ostream& out, const Date& d);

	// 使用流提取获取日期
	friend std::istream& operator>>(std::istream& in,  Date& d);


private:
// 成员变量
	int _year;
	int _month;
	int _day;
};

上述代码中需要注意几个细节,因为我们今天实现的是一个日期类的项目,我们我们代码 的书写需要规范一点,平时我们自己在练习写代码的时候通常都是将std整个命名空间的内容全部展开,这样其实是不规范的,今天我们写项目就是需要使用什么就将什么展开,尽量展开需要经常使用的东西。

  • 上面的函数声明中,有的函数在最后会加上const关键字,有点函数却没有,这是为啥?
    这个涉及的是 const成员函数的知识点,我们知道,在类的成员函数中会隐藏一个指针:this,这个指针的类型是Date* const ,也就是Date* const this,这个const修饰的是this,也就是限制this不能被改变(可以初始化),但是this指向的对象是可以发生改变的,为了防止一些不需要修改调用成员函数的对象的函数中误操作对对象进行修改,我们考虑对this进行保护,也就是在this前加上const,本来应该是:const Date* const this,但是我们知道,this指针是编译器处理的,我们通常不需要显示处理,所以这个const就放在了括号外,也就是上面这种样子。

下面源文件中的代码需要定义各个函数的具体细节,以下会分函数进行讲解。

二、构造函数

  • 基本代码
// 判断闰年
bool Date::isLeapYear(int year)  const
{
	return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 求每个月的天数
int Date::GetMonthDay(int year, int month)  const
{
	int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (isLeapYear(year) && month == 2)
	{
		return 29;
	}
	else
	{
		return arr[month];
	}
}

// 构造函数
Date::Date(int year, int month, int day)
{
	if (year > 0 && month > 0 && month < 13 && day>0 && day < GetMonthDay(year, month))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "输入的如期不合法" << endl;
	}
}

分析:在实现构造函数的时候,我们不能直接将传进来的参数直接对对象中的成员变量进行初始化,因为用户传进来的数值可能是不合法的,所以我们需要对其进行判断,判断的原则年大于0,月在1到12,天数大于0,但是需要小于等于当前月的最大天数。显然我们需要一个函数去求解每一年中每一个月的天数,实现这个函数中显然需要考虑平年和闰年的问题,我们首先考虑常规情况,也就是假设为平年,将每一年的天数存放到一个数组中,这个数组在实现的时候也有一个技巧,我们多开一个空间,因为这样的话,传进来的是哪一个月,那么其天数就算数组中对应下标的位置存储的值,然后再考虑特殊情况,也就算闰年的情况,如果是闰年,并且是2月,那么天数就应该是29。实现闰年的时候就是一个逻辑:4年一闰,百年不闰,400年再闰一次

三、拷贝构造函数

对于日期类,因为类中不存在动态开辟的资源,因此浅拷贝就能够实现对象的拷贝构造,我们不写编译器自动生成的拷贝构造函数就能够实现日期类的浅拷贝功能,但是为了练习,我们今天还是实现以下日期类的拷贝构造函数。代码如下:

// 拷贝构造函数
Date::Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

拷贝构造函数实现中需要注意一个细节:参数必须采用引用传参,否则会引发无穷递归,同时如果不会改变被拷贝的对象,需要加上const进行修饰,防止被拷贝对象被修改。

四、赋值运算符重载

// 赋值运算符重载
Date& Date::operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

赋值运算符重载函数中需要注意:

  • 参数:传递的参数是一个自定义类型,是一次拷贝,我们可以实现成传引用参数,这样可以减少一次拷贝,较少消耗。
  • 赋值自己:赋值前检查是否为自己给自己赋值,通过this和d的地址进行判断,如果是则不需要进行赋值操作
  • 返回值:赋值运算通常是支持连续赋值的,所以一次赋值后的结果应该是上一次赋值后的左值。

五、日期比较

1. 判断一个日期是否小于另一个日期

// 比较日期
bool Date::operator<(const Date& d)  const
{
	return (_year < d._year) ||
		(_year == d._year && _month < d._month) ||
		(_year == d._year && _month == d._month && _day < d._day);
}

判断的逻辑:

  1. 如果年小,则小于
  2. 如果年相等,则看月,月小则小于
  3. 如果年相等,月相等,则看天,天小则小于

2. 判断一个日期和另一个日期是否相等

bool Date::operator==(const Date& d)  const
{
	return _year == d._year &&
		_month == d._month &&
		_day == d._day;
}

判断两个日期是否相等的依据是:两个日期的年月日分别对应相等。

3. 判断一个日期是否小于等于另一个日期

bool Date::operator<=(const Date& d)  const
{
	return *this < d || *this == d;
}

这个函数可以采用复用的原则,因为一个日期小于等于另一个日期的情况就是:一个日期小于另一个日期,一个日期等于另一个日期。

4. 判断一个日期是否大于另一个日期

bool Date::operator>(const Date& d)  const
{
	return !(*this <= d);
}

这个函数同样可以采用复用,通过逻辑反操作来进行实现,因为我们要判断一个日期是否大于另一个日期,我们可以通过相反的情况进行分析:如果这个日期小于等于另一个日期,那么这个日期肯定不大于另一个日期,用代码的角度来进行解释的话:如果一个日期小于等于另一个日期,那么小于等于的判断就为真,但是实际上这个是不大于的,所以在前面的基础上再加上逻辑反操作即可。

5. 判断一个日期是否大于等于另一个日期

bool Date::operator>=(const Date& d)  const
{
	return *this > d || *this == d;

采用复用即可实现

六、日期+天数 = 天数后的日期

  • 思路1
// 思路1:
Date Date::operator+(int day)  const
{
	Date ret(*this);
	ret._day += day;
	while (ret._day > GetMonthDay(ret._year, ret._month))
	{
		ret._day -= GetMonthDay(ret._year, ret._month);
		--ret._month;
		if (ret._month == 0)
		{
			ret._month = 12;
			--ret._year;
		}
	}
	return ret;
}

思想:首先要知道的是,日期+天数是不会改变原有的日期的,所以我们需要利用原来的日期来拷贝构造一个一模一样的日期,然后再在拷贝出来的日期进行处理。首先,直接将day加到拷贝出来的日期,加上之后的日期中的天数可能会超出当前月的天数,那么就显然需要进行调整,这时就需要加上当前月的天数,然后月数加1,在月数++的过程中可能会出现月数超过12的情况,那么这个时候需要对月数进行处理,也就是到下一年的情况了,当日期中的天数没有超出当前月的天数时此时日期就是合法的,也就是最终的结果。

  • 思路2
// 思路2
Date Date::operator+(int day)  const
{
	Date ret(*this);
	while (day--)
	{
		ret._day++;
		if (ret._day > GetMonthDay(ret._year, ret._month))
		{
			ret._day = 1;
			ret._month++;
		}
		if (ret._month == 13)
		{
			ret._month = 1;
			ret._year++;
		}
	}
	return ret;
}

思想:思想与第一种思想有所不同,这个思路的思想是要求几天后,那么就循环将日期增加几次,其中的月数和闰年的情况全部在GetMonthDay(year,month)函数中会考虑,在增加的过程中出现的临界:

  • 天数增加到大于当前月的最大值:日期变成下一个月的1号,调整:月数++,天数变成1
  • 月数增加到大于12:跨年,月份变成下一年的一月,调整:年份++,月份变成1月

七、日期+=天数 = 天数后的日期

  • 思路1
// 思路1:复用
Date& Date::operator+=(int day)
{
	*this = *this + day;
	return *this;
}

  • 思路2
// 思路2:
Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}
  • 思路3
// 思路3:
Date& Date::operator+=(int day)
{
	while (day--)
	{
		_day++;
		if (_day > GetMonthDay(_year, _month))
		{
			_day = 1;
			_month++;
		}
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}

八、日期-天数 = 天数前的日期

  • 思路1
// 日期-天数 = 日期
Date Date::operator-(int day)  const
{
	Date ret(*this);
	ret._day -= day;
	while (ret._day <= 0)
	{
		ret._month--;
		if (ret._month == 0)
		{
			ret._month = 12;
			ret._year--;
		}
		ret._day += GetMonthDay(ret._year, ret._month);
	}
	return ret;
}

思想:和加法一样,原来的日期是不会变的,所以需要拷贝一个临时对象进行处理。先将原来日期中的天数减小day,减小之后的日期中的天数可能会出现小于等于0,那么显然是不合法的,所以就需要进行处理。当日期中的天数是小于等于0时,此时需要上一个月的天数来进行调整,有点类似于借位,所以需要先月份–,退到上一个月,退到上一个月可能会出现跨年的情况,所以需要进行判断,如果月份减小到0,那么此时就是需要到上一年的12月,也就是年份–,月份等于12,当月份没问题时,求上一个月的天数,加到日期的天数。重复上述逻辑,知道日期的天数大于0时,日期合法,退出循环。

  • 思路2
// 思路2
Date Date::operator-(int day)  const
{
	Date ret(*this);
	while (day--)
	{
		ret._day--;
		if (ret._day == 0)
		{
			ret._month--;
			if (ret._month == 0)
			{
				ret._month = 12;
				ret._year--;
			}
			ret._day = GetMonthDay(ret._year, ret._month);
		}

	}
	return ret;
}

思想:减少几天,那么日期就向前退几天,那么循环就循环几次,在循环的处理过程中,同样可能出现一些边界需要处理。当日期的天数减小到0时,此时需要调整到上一个月的最后一天,当月份减小到0时,此时需要调整到上一年的最后一个月。

九、日期-=天数 = 天数前的日期

  • 思路1
// 思路1:复用
Date& Date::operator-=(int day)
{
	*this = *this - day;
	return *this;
}
  • 思路2
// 思路2
Date& Date::operator-=(int day)
{
	while (day--)
	{
		_day--;
		if (_day == 0)
		{
			--_month;
			if (_month == 0)
			{
				_month = 12;
				_year--;
			}
			_day = GetMonthDay(_year, _month);
		}
	}
	return *this;
}
  • 思路3
// 思路3
Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

十、日期的++ = 日期

1. 前置++

// 前置++
Date& Date::operator++()
{
	*this = *this + 1;
	return *this;
}

前置++:先++,再返回,返回的是++后的日期,所以直接对原来的日期进行处理即可,出了函数,返回的日期仍然存在,所以返回值用引用。

2. 后置++

// 后置++
Date Date::operator++(int)
{
	Date ret(*this);
	*this = *this + 1;
	return ret;
}

后置++:先返回,后++,返回的是++前的日期,所以需要先保存++前的值,再处理原来的日期,然后将此临时对象返回,返回的临时对象显然在函数结束后是不存在的,所以不能用引用返回,只能传值返回。

十一、日期的-- = 日期

分析方法与++一致!

1. 前置–

// 前置--
Date& Date::operator--()
{
	*this = *this - 1;
	return *this;
}

2. 后置–

// 后置--
Date Date::operator--(int)
{
	Date ret(*this);
	*this = *this - 1;
	return *this;
}

十二、日期-日期 = 相差天数

// 日期-日期 = 相差天数
int Date::operator-(const Date& d)  const
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	int count = 0;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	while (min < max)
	{
		min++;
		count++;
	}

	return flag * count;
}

思想:本质就是一个追击相遇问题,先确定两个日期中的大日期和小日期,显然,如果是大日期-小日期,结果是正数。如果小日期-大日期,结果是负数。
确定方法:假设第一个日期(this)是大日期,第二个日期是小日期(d),最终this-d>0,此时设置一个标记位1记录结果的符号。如果上述假设不成立,那么就是第一个日期(this)是小的,第二个日期是大日期,结果是负数,即this-d<0。然后使用一个循环让小日期去追击大日期,当小日期还没有到大日期时,小日期的天数+1,知道小日期追上大日期时结束循环。

十三、日期的流插入和流提取运算

这个函数不能声明为成员函数,因为如果声明为成员函数,那么第一个参数就默认是日期,第二个参数才是cout了,这样的顺序显然是不对的,所以这个函数不能是类的成员函数。
通过上面的分析,这个函数只能是类外的函数,但是类外的函数又会遇到一个问题:不能访问类中的私有成员,此时就需要将这个函数设计成这个类的友元函数,设计方法:在类中使用friend关键字声明该函数,在对应的源文件中定义该函数,注意不能在头文件中定义该函数,否则在链接的时候会出现重定义。

1、日期的流插入

std::ostream& operator<<(std::ostream& out, const Date& d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}

上述的函数需要实现的就是将日期输出到显示器上,显然日期类是一个自定义类型,cout并不知道要以怎样的形式将日期输出,所以这个时候需要采用运算符重载重载函数中需要注意:

  • 参数:第一个参数是cout的别名,第二个参数是输出日期的别名。函数中只需要输出日期,并不会对日期进行修改,所以参数中日期前可以加上const关键字,防止输出日期被修改。
  • 返回值:因为流插入输出时是支持连续输出的,所以这个运算符在重载的时候是需要通过控制函数返回值来实现连续输出的,返回的显然是ostream类型的对象,函数结束后,对象仍然存在,所以需要传引用返回。

2. 日期的流提取

std::istream& operator>>(std::istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

这个函数的功能主要是从流中提取日期的内容,在实现的时候,需要注意以下方面:

  • 参数:第一个参数是cin的别名,第二个参数是待处理日期的别名,注意这个日期不能加上const关键字进行修饰,因为我们在函数中是需要对这个日期的类型进行修改的。
  • 返回值:和<<运算符重载一样的道理。

十四、打印日期

// 打印日期
	void Print()const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

当我们没有实现流插入运算符重载时i,我们可以考虑通过实现这个成员函数将对象中的内容输出,但是通过这样的方法代码的可读性就比较低了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197996.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

独孤九剑xss通关教程

独孤九剑xss通关教程 独孤九剑第一式&#xff1a; 这里过滤了 () 构造payload&#xff1a; ?data"><svg><script>%26%23x65%3B%26%23x76%3B%26%23x61%3B%26%23x6c%3B%26%23x28%3B%26%23x6c%3B%26%23x6f%3B%26%23x63%3B%26%23x61%3B%26%23x74%3B%26%23…

开门红,农民大衣哥兔年第一条祝福,为何在百万艺人中选择杨语莲

俗话说&#xff1a;人逢喜事精神爽。这句话用到农民歌唱家大衣哥身上&#xff0c;就再贴切不过了&#xff0c;因为在新年即将来临之际&#xff0c;他的儿子小伟又一次结婚了。大衣哥是一个非常接地气的明星&#xff0c;这些年来他无绯闻不炒作&#xff0c;堪称为娱乐圈的楷模&a…

开学季,送初三学生什么礼物最实用?2023学生护眼台灯分享

春节的新学期即将到来&#xff0c;送给初中孩子什么礼物比较好呢&#xff0c;还是要对学习有所帮助的&#xff0c;还需要培养孩子的兴趣&#xff0c;在挑选礼物时&#xff0c;也是斟酌了很久&#xff0c;面对现在很多孩子的有近视问题&#xff0c;在我国的近视人数达到7亿人&am…

java面试题(十一)IO流篇

2.21 请介绍TreeMap的底层原理 参考答案 TreeMap基于红黑树&#xff08;Red-Black tree&#xff09;实现。映射根据其键的自然顺序进行排序&#xff0c;或者根据创建映射时提供的 Comparator 进行排序&#xff0c;具体取决于使用的构造方法。TreeMap的基本操作containsKey、g…

三维重建——商汤NeuralRecon算法详解与论文解读

论文地址:https://arxiv.org/abs/2104.00681 1.三维重建任务概述 三维重建,就是将2D的图片信息重建为3D的信息。应用领域广泛。可以应用于原型设计、虚拟现实等。 2.三维重建基础 (1) 相机成像 相机成像一般是小孔成像的原理,f就是焦距,o就是光圈;右图为光圈大小对清晰…

【多尺度注意力的轻量化图像超分辨率】

MSAR-Net: Multi-scale attention based light-weight image super-resolution &#xff08;MSAR-Net&#xff1a;基于多尺度注意力的轻量化图像超分辨率&#xff09; 近年来&#xff0c;单幅图像超分辨率&#xff08;SISR&#xff09;技术在视频和图像处理领域得到了广泛的应…

Python基础语法预习,开学查漏补缺

嗨害大家好鸭~我是小熊猫 Python3 基础语法 Python学习资料电子书 点击此处跳转文末名片 编码 默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c; 所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码&#xff1a; # -*- coding: cp-125…

(HR职场)什么是计划能力?如何提高计划能力?

不论是学习还是工作&#xff0c;光靠努力是不行的&#xff0c;还得有计划&#xff0c;有周密的部署&#xff0c;懂得按计划做事情的人&#xff0c;不仅可以高效率地完成工作&#xff0c;还能在枯燥的工作中寻找到乐趣。这就是做计划的意义和必要性。当然光有计划也不行&#xf…

ArcGIS基础:将多个面要素融合成一个多边形面要素操作

操作目标&#xff1a;有多个多边形要素&#xff0c;并且字段属性没有统一的&#xff0c;可以采用以下两种办法融合成一个面要素。 如下所示&#xff0c;是对被选中的高亮数据进行处理的。 下面介绍第一种方法&#xff1a; 保持数据选中状态&#xff0c;找到【地理处理】下的…

Codeforces Round #849 (Div. 4) D Distinct Split

题目&#xff1a;大概翻译&#xff1a;让我们把一个字符串x的f(z)函数表示为该字符串包含的不同字符数。例如&#xff0c;f(abc)3。f(bbbb) 1, 和 f(babacaba) 3. 给定一个字符串s&#xff0c;将其分成两个非空字符串a和b&#xff0c;使f(a)f(b)为最大可能。换句话说&#xf…

2023软考软件设计师易混淆知识点~(7)

将2023上半年软考《软件设计师》易混淆知识点&#xff0c;分享给大家&#xff0c;快来跟着一起打卡学习吧&#xff01;--<<<点击链接加入群聊【软考学习交流群】>>>易混淆点 :对称加密和非对称加密1、对称加密技术:KeKd;加密解密共用一个密钥;特点:加密强度不…

python设计模式-适配器设计模式,装饰器设计模式

适配器设计模式 适配器模式可用作两个不兼容接口之间的桥梁。 这种类型的设计模式属于结构模式&#xff0c;因为此模式结合了两个独立接口的功能。 这种模式涉及一个类&#xff0c;它负责连接独立或不兼容接口的功能。 一个现实的例子是读卡器&#xff0c;它是存储卡和笔记本电…

超多免费API接口分享

分享一下近段时间在网上看的超多免费API接口&#xff0c;赶紧收藏起来吧&#xff01; 一、APISpace 为超过100 万开发者提供专业的 API 服务&#xff0c;包括 API 管理、测试、访问控制等功能&#xff0c;让您无忧探索广阔的API世界~所有接口提供免费试用 https://www.apisp…

【最坏贪心】代码源每日一题div1 排列 2023.02.03

排列 - 题目 - Daimayuan Online Judge今天牛牛完结撒花辣&#xff01;但是我还没补完题&#xff0c;感觉这几场rk都差不多&#xff0c;但是总体来说感觉签到签的有点困难&#xff0c;然后好不容易开到算法题&#xff0c;算法的题也最多只能出一题然后后面这几天除了vpCF&#…

现在都这么拽吗?面试一个工作4年的测试工程师,连自动化基础都搞不清楚,还反过来怼我....

年后招聘黄金期&#xff0c;我们公司也开始大量招人了&#xff0c;我这次是公司招聘的面试官之一&#xff0c;主要负责一些技术上的考核&#xff0c;这段时间还真让我碰到了不少奇葩求职者 昨天公司的HR小席刚跟我吐槽&#xff1a;这几个星期没有哪天不加班的&#xff01;各种…

代码随想录 day55动态规划 回文子串

代码随想录 day55动态规划 回文子串 题647 回文子串 动态规划解法&#xff1a; 1&#xff0c;确定dp数组以及下标的含义 对于绝大多数题目来说&#xff0c;题目求什么dp数组就定义为什么&#xff0c;但此题如果定义&#xff0c;dp[i] 为 下标i结尾的字符串有 dp[i]个回文串的…

【2003NOIP普及组】T3.栈 试题解析

【2003NOIP普及组】T3.栈 试题解析 时间限制: 1000 ms 内存限制: 65536 KB 【题目描述】 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈)。 栈的重要…

对比coco anationtions和coco result的数据保存形式

一、背景 coco anationtions是coco数据集提供的数据标签&#xff0c;coco result是预测的结果的形式&#xff0c;方便用pycocotools计算模型的map等指标。 二、两种数据形式对比 1. coco anationtions的形式 以person_keypoints_val2017.json为例。整体结构如下图 是一个字…

服务器搭建原神私服教程

1. 准备工具这个端在Windows、Linux系统上都可以跑&#xff0c;本次教程基于Linux。准备如下工具服务器1台 centos7 系统 最低配置8核16G 如需公网联机可用云服务器手保证云服务器的443端口未使用&#xff08;服务器上没有网站&#xff09;2. 环境配置安装系统依赖环境yum -y i…

揭密字节跳动薪资职级,资深测试居然能拿......

曾经的互联网是PC的时代&#xff0c;随着智能手机的普及&#xff0c;移动互联网开始飞速崛起。而字节跳动抓住了这波机遇&#xff0c;2015年&#xff0c;字节跳动全面加码短视频&#xff0c;从那以后&#xff0c;抖音成为了字节跳动用户、收入和估值的最大增长引擎。 自从字节逐…