本文为每日打卡计划
目录
一、LeetCode-59:螺旋矩阵
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));
int startx = 0, starty = 0;
int loop = n/2, mid = n/2;
int offset = 1, count = 1;
while(loop--){
int i = startx, j = starty;
for(; j < n - offset; j++){
res[i][j] = count++;
}
for(; i < n - offset; i++){
res[i][j] = count++;
}
for(; j > starty; j--){
res[i][j] = count++;
}
for(; i > startx; i--){
res[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if(n % 2){
// res[mid][mid] = n*n;
res[mid][mid] = count;
}
return res;
}
};
二、剑指offer-1:赋值运算符函数
1.赋值运算符函数介绍
运算符重载是C++一种形式的多态,允许赋予C++运算符多种含义。
例如我们有一个Time类,包括小时和分钟,平常我们是没法直接让两个Time类相加获取总的小时分钟的。这时我们可以使用对+运算符重载。
基础知识:ifndef与define头文件、函数、类和对象、构造函数和析构函数、const关键字、友元函数
1.1 未使用重载形式的写法
MyTime.h头文件:
#ifndef MYTIME_H_
#define MYTIME_H_
class Time
{
private:
int hour;
int minute;
public:
Time();
Time(int h,int m);
//和另一个类时间相加
Time Sum(const Time& t) const;
//输出当前类表示的时间
void Show();
};
#endif // !MYTIME_H_
MyTime.cpp头文件方法实现:
#include <iostream>
#include <string.h>
#include "MyTime.h"
Time::Time() {
hour = minute = 0;
}
Time::Time(int h, int m) {
hour = h;
minute = m;
}
Time Time::Sum(const Time& t) const {
Time sum;
sum.minute = minute + t.minute;
sum.hour = hour + t.hour + sum.minute / 60;
sum.minute %= 60;
return sum;
}
void Time::Show() {
std::cout << hour << " " << minute << std::endl;
}
main.cpp:
#include <iostream>
#include "MyTime.h"
int main() {
Time t1(2, 30);
Time t2(2, 30);
Time total = t1.Sum(t2);
total.Show();
//输出时间 5 0
return 0;
}
1.2 使用重载形式的写法
MyTime.h头文件:
#ifndef MYTIME_H_
#define MYTIME_H_
class Time
{
private:
int hour;
int minute;
public:
Time();
Time(int h,int m);
//和另一个类时间相加
Time operator+(const Time& t) const;
//输出当前类表示的时间
void Show();
};
#endif // !MYTIME_H_
MyTime.cpp 头文件方法实现:
#include <iostream>
#include <string.h>
#include "MyTime.h"
Time::Time() {
hour = minute = 0;
}
Time::Time(int h, int m) {
hour = h;
minute = m;
}
Time Time::operator+(const Time& t) const
{
Time sum;
sum.minute = minute + t.minute;
sum.hour = hour + t.hour + sum.minute / 60;
sum.minute %= 60;
return sum;
}
void Time::Show() {
std::cout << hour << " " << minute << std::endl;
}
main.cpp:
#include <iostream>
#include "MyTime.h"
int main() {
Time t1(2, 30);
Time t2(2, 30);
//这种写法会被自动转换成下面
Time total = t1 + t2;
//Time total = t1.operator+ (t2);
total.Show();
//输出时间 5 0
return 0;
}
1.3 完整的例子
下面例子主要演示用法,不在细算小时与分钟。
后面会对此例子进行完整的讲解。
MyTime.h 头文件:
#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
#include <iostream>
class Time
{
private:
int hour;
int minute;
public:
Time();
Time(int h, int m);
///重载+运算符
Time operator+(const Time& t) const;
///重载-运算符。一个减法、一个取反
Time operator-(const Time& t) const;
Time operator-() const;
///重载*运算符。
Time operator*(int m) const;
friend Time operator*(int m, const Time& t);
///输出类时间
friend std::ostream& operator<<(std::ostream& os, const Time& t);
};
#endif // HEAD_H_INCLUDED
MyTime.cpp 头文件方法实现:
#include <iostream>
#include <string.h>
#include <string>
#include "head.h"
Time::Time() {
hour = minute = 0;
}
Time::Time(int h, int m) {
hour = h;
minute = m;
}
Time Time::operator+(const Time& t) const
{
Time sum;
sum.minute = minute + t.minute;
sum.hour = hour + t.hour + sum.minute / 60;
sum.minute %= 60;
return sum;
}
Time Time::operator-(const Time& t) const
{
Time temp;
temp.minute = minute - t.minute;
temp.hour = hour - t.hour;
temp.minute %= 60;
return temp;
}
Time Time::operator-() const
{
return Time(-hour,-minute);
}
Time Time::operator*(int m) const
{
Time temp;
temp.hour = hour*m + minute*m / 60;
temp.minute = minute*m % 60;
return temp;
}
Time operator*(int m, const Time& t) {
Time temp;
temp.hour = t.hour*m + t.minute*m / 60;
temp.minute = t.minute*m % 60;
return temp;
}
std::ostream& operator<<(std::ostream& os,const Time& t)
{
os<<"小时:"<<t.hour<<" 分钟:"<<t.minute<<std::endl;
return os;
}
main.cpp
#include "head.h"
#include <iostream>
using std::cout;
using std::string;
using std::endl;
int main()
{
Time t1(2,30),t2(2,30);
t1 = t1+t2;
cout<<t1;
t1 = t1-t2;
cout<<t1;
t1 = -t1;
cout<<t1;
t1 = 2*t1;
cout<<t1;
t1 = t1*2;
cout<<t1;
return 0;
}
重载 * 运算符:
对于乘法,可以注意到我们加了一个友元函数对其进行重载。这是为什么呢?
//当运算符在对象后面时,t1*2会自动被识别为t1.operator*(2),调用函数
t1 = t1*2;
cout<<t1;
//但是当运算符在对象前面时,其并不能被识别为t1.operator*(2)
//这时就需要使用友元函数*进行重载
t1 = 2*t1;
cout<<t1;
重载 - 运算符:
还有一种比较特殊的情况我们并不需要友元函数也能让运算符在前面进行重载。对于 - 运算符,平常我们会有两种情况的用法。
1、减法运算符,使用两个操作数。(x-y)
2、负号运算符,使用一个操作数。(-x)
通过例子可以发现,当我们重载第二种负号运算符的用法时,就可以在对象前面使用了。
重载 << 运算符:
friend std::ostream& operator<<(std::ostream& os, const Time& t);
对于<<比较特殊,cout是std命名空间中ostream的一个输出流对象,并且因为ostream没有默认复制函数,所以我们使用&获取ostream的引用。
另外因为cout可以连续使用<<进行输出,所以我们返回os的引用
分析下面语句:
cout<<t1<<t2<<"hello world"; 等价于
( (cout<<t1) <<t2) <<"hello world";
第一步cout<<t1,调用Time类中的重载,并返回cout对象。
第二步cout<<t2,调用Time类中的重载,并返回cout对象。
第三步cout<<"hello world",调用ostream中的<<定义,并返回cout对象。
2.剑指offer面试题-1
给如下类型添加赋值运算符函数。
class CMyString {
private:
char* m_pData;
public:
CMyString(const char* pData = nullptr);
CMyString(const CMyString& str);
~CMyString();
};
解答:
//使用&,跟参数+地址符一样,可以节省内存
CMyString& CMyString::operator=(const CMyString& str)
{
//判断参数str是否是当前对象实例,是就直接返回
if (this == &str)
return *this;
//重新给data赋值
delete []m_pData;
m_pData = nullptr;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy_s(m_pData, strlen(str.m_pData) + 1, str.m_pData);
return *this;
}