未解决:
2022.4.27~2022.5.17
- 为什么不能写成
(d[n]==0x3f3f3f3f)?return -1:return d[n];
,而必须写成return (d[n]==0x3f3f3f3f)?-1:d[n];
- a+b和b+a是否不同,不同之处在哪里?
已解决&心得&教训:
2022.6.2
- 在读入数据之前务必看清楚数据类型。int存不了char,如果用int数组直接读入字符串会出错。即便单个读入也不行。
2022.5.18
- c++中定义了一个指针,欲为其开辟数组空间并指向该空间或者删除该指针指向的数组空间时:
p = new int [maxx];
delete []p;
2022.4.27~2022.5.17
- 用
scanf
取字符很危险,如果一定要挨个取字符,就用cin
取,因为cin
在取字符时和scanf
取字符串时一样,会自动忽略空格或换行。 - 在写归并排序,写KMP,模拟队列或者栈等等问题时,千万注意下标问题。
- 用邻接表建图务必提前将head数组初始化为-1,为什么?用0很危险,我们有时可能会不注意存到0中去,并且0也不符合习惯。
- 读题读题再读题!例如搞混到底是有向边还是无向边这种问题不要再出现!
unordered_map()
速度真的很快!另外能少用STL的队列或栈就少用,数组模拟会快很多很多。有时超时就是多用了一个队列的事。const int N=100010;
而不是const int N=1e5+10;
一个看似无伤大雅的问题。其实真的无伤大雅- 不要盲目用题目所给范围,例如离散化,邻接表等等,要开的数组范围往往是题目所给的几倍。要注意观察。
- 快排中不仅
i=l-1,j=r+1;
需要注意,另外while(i<j)
,while(a[i]<x)
,while(a[j]>x)
都要注意,均是’<‘,而不是’<='。 - 要么写成
e[++idx]=y,ne[idx]=h[x],h[x]=idx;
要么写成e[idx]=y,ne[idx]=h[x],h[x]=idx++;
总之不能写成e[idx++]=y,ne[idx]=h[x],h[x]=idx;
这样起点和终点就不在同一条边上了 - 类内函数体外只能定义全局变量和对象,不能执行语句或调用函数。
- c++中实现构造函数的成员初始化表:
为什么要用成员初始化表?1.当我们在类中声明了一个引用,我们必须对引用进行初始化,但是类的数据成员又不允许有赋值操作,怎么办?可以放在构造函数的成员初始化表中。2.引用类型同样需要赋初值。3.对象成员的初始化。
Xinyi::Xinyi(int a,int b,int c):nian(a),yue(b),ri(c)
{
//nian = a, yue = b, ri = c;
cout << nian << " " << yue << " " << ri << endl;
}
- 当我们在写一个带默认参数的构造函数时,不要在定义和实现处都给参数赋初值,否则将显示
我们可以在声明处给虚参赋初值,在函数实现时不再赋值。另外如果我们这样做将不能再定义一个不带参数的构造函数,否则将产生二义性。 - 内联函数的声明和实现都要在头文件内完成,因为系统会将内联函数自动移动到主函数内,必须提前知道内联函数是啥。如下图:
- 是否可以让基类在它派生类的后面 ? 不可以
- 怎么在子类的成员函数中调用父类的同名函数?通过在函数名前加作用域来实现。
- 为什么在类中定义的静态数据成员要在类外赋初值?其实赋初值只是一个形式,我们真正地目的是定义静态数据成员。
“静态成员变量是需要初始化的”是有一定问题的,应该说“静态成员变量需要定义”才是准确的,而不是初始化。
两者的区别在于:初始化是赋一个初始值,而定义是分配内存。
静态成员变量在类中仅仅是声明,没有定义,所以要在类的外面定义,实际上是给静态成员变量分配内存。
- 当我们由一个基类派生出多个派生类时,我们定义了一个基类的指针数组,每个指针分别指向不同的派生类,我们希望能区分指向不同派生类的指针,怎么办呢?我们可以用typeid函数,使用函数前必须加上
#include<typeinfo>
头文件。
参考以下伪代码:
#include<iostream>
#include<typeinfo>
class A{};
class B:A{};
A *p=new A;
A *q=new B;
//如果我们想判断p和q是否指向同一种类,我们可以
if(typeid(*p)==typeid(*q))cout<<"YES"; //注意,要用*来解引用,否则返回的是指针的类型,而不是类的类型
else cout<<"NO";
//如果我们只是想知道p指向了什么类,我们可以
cout<<typeid(*p).name();
- 在主程序中添加类的头文件时,不要忘记加.h后缀。
- 不管用不用的到,先加上这两行代码总是没错的:
#include<iostream>
using namespace std;
例如在类的声明文件中,如果我们想重载>>和<<,那就不能少了这两句。而这种错误一般是很难找到的。
- 任何时候注意边界问题,特别是涉及到指针时:
//这个程序中我想要释放count个指针指向的空间,但是忽略了i是从0开始的,所以程序运行时就出错了。
for (int i = 0; i < count; ++i)//注意是i<count,而不是i<=
delete pCe[i];
- 做动态规划问题时,如果涉及到
f[i-1]
那么循环最好是从1开始。
奇淫巧技小技巧:
2022.4.27~2022.5.17
sort( a+1, a+n+1, [ ](int x, int y) {return a < b }; );
struct ss
{
int a,b,w;
bool operator <(const ss &a)const
{
return w<a.w;
}
}s[N];
更新日志:
2002.5.18
更新了new和delete对数组指针的操作。