文章目录
- TODO-LIST
- void返回值return;有必要吗?
- 返回值为void的函数需要写return吗?
- vector\<int> vec;//会调用默认无参构造函数
- size与capacity的区别
- 字符串empty()函数
- struct、class存储在栈中(待解决11/21)
- 回溯法
- 大数求余
- 位运算
- double判断等于0
- 负数变正数:取值范围导致数据类型变化
- stirng判空
- C++建立动态二维数组
- c++不能通过+拼接string与int
- 递归时间复杂度计算公式
- 排序时间复杂度
- java对象内存自动回收
- c++用new创建对象
- C++之对象的赋值与复制(拷贝构造函数)
- char为1个字节
- 位运算常用技巧
- 乘法溢出问题
- 用++i替换do while
TODO-LIST
- 优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。
void返回值return;有必要吗?
在返回类型为 void 的函数中,return 返回语句不是必需的,隐式的 return 发生在函数的最后一个语句完成时。一般情况下,返回类型是 void 的函数使用 return 语句是为了引起函数的强制结束。
表达编程思想呀! 如果是在该结束的地方return; 与不写是一样的,这个有编译器来处理的.
为了好的编程习惯,还是加上的好.
有时候可能会考虑到使用递归思想解决问题,这时即使是void ,你也要return
返回值为void的函数需要写return吗?
- 在返回类型为 void 的函数中,return 返回语句不是必需的。
- 隐式的 return 发生在函数的最后一个语句完成时。编译器会自动添加return。
- 一般情况下,返回类型是 void 的函数使用 return 语句是为了引起函数的强制结束(好的编程习惯应该写return)。
- 用递归解决问题时,有时必须用return控制。
vector<int> vec;//会调用默认无参构造函数
此时size为0.
如果定义的是一个对象指针,则不会调用构造函数。也不分配空间,必须用new。
size与capacity的区别
- size是当前容器vec1存实际储了多少个元素
- capacity是这个vector即vec1,最多可以存储多少个元素,vec1总共申请了多大内存空间,包括已使用和未使用的。
- maxSize是这类容器如vector最多可以存储多少个元素,由系统或者库来限制。
-
vector容器的容量不是确定的,而是当当前容量不足,就扩大一倍(十分耗时,使用reserve函数)。
-
扩容步骤:
- 完全弃用现有的内存空间,重新申请更大的内存空间;
- 将旧内存空间中的数据,按原有顺序移动到新的内存空间中
- 最后将旧的内存空间释放。
-
resize函数
void resize (size_type n);
void resize (size_type n, const value_type& val); //新元素初始为val
n < size 保留前n个元素
n > size 末尾插入
n > capacity 扩容
字符串empty()函数
坑:empty() 函数对 “0” 也返回true。可以用
if(value == "") //判断字符串为空
- 格式:bool empty ( mixed var )
- 功能:检查一个变量是否为空
- 返回值:
- 若变量不存在则返回 TRUE
- 若变量存在且其值为 “”、0、“0”、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回 TURE
- 若变量存在且值不为""、0、“0”、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回 FALSE
struct、class存储在栈中(待解决11/21)
回溯法
回溯法是基于递归的。
核心就是for循环里的递归,在递归之前做选择,在递归之后撤销选择;
在这个过程中还有一点很重要,就是我们其实是在做两种遍历;
- 横向遍历(for):其实就是我们在不停的做着的选择;
- 纵向遍历(递归):其实就是在做完选择后面临的下一轮选择;
其实不同的情境下最大的不同就在于决策列表的更新,比如说搜索起点和终点,比如说是否已经被选过,比如说是否达到某个条件(只要求k个数或者和为目标值);
1.只要是涉及到做选择的,尤其是提到的五个类型:组合、排序、分割、子集、棋盘。这种都可以构建一颗决策树,那就都可以用回溯算法去解。解之前先自己把决策树画出来。
2.整体上套用模板,最大的不同就在于选择列表的更新,要能够根据题目中的要求来更新选择列表,比如到达某个深度了,比如和为某个值了等等;
3.在求和问题中,排序之后加上剪枝是很常见的操作,能够舍弃无关的操作(和已经到达某一值了,因为排过序,其后的值就更大了);
大数求余
位运算
n & (1 << i) //如果n的二进制数的第i位为1,结果为真
n = n & (n - 1) //将n的二进制数的最后一个1变为0如:6&(6-1) = 4, 6 = (110)_2, 4 = (100), 6 & (6−1)=4
double判断等于0
#define MIN_VALUE 1e-8
#define IS_DOUBLE_ZERO(d) (abs(d) < MIN_VALUE)
负数变正数:取值范围导致数据类型变化
int(32位)取值范围:-231 <= n <= 231-1
负数 n=-231,-n用int表示为231会溢出。要用long long(64位)。c++标准中long也是32位。
stirng判空
不能使用str==NULL来判断,NULL一般只拿和指针做比较或者赋给指针,string是类,传参进函数时str调用默认的构造函数已经初始化了,并且str都已经是对象了,它不可能为NULL,也不能和NULL比较。
string判空
C++建立动态二维数组
c++不能通过+拼接string与int
java:“123”+3可行,即可通过+将string与int拼接,c++未重载+运算符
int与string互相转换
string转int
递归时间复杂度计算公式
排序时间复杂度
稳定:冒查(插)疾(基)病(并)
排序时间复杂度
java对象内存自动回收
- java必须用new创建对象
- java对象一般存储在堆中,且自动回收
java对象一定在堆中吗?
c++用new创建对象
使用new创建的特点:
- new创建类对象使用完需delete销毁。
- new创建类对象需要指针接收,一处初始化,多处使用。
- new创建对象直接使用堆空间,而局部不用new定义类对象则使用栈空间。
- new对象指针用途广泛,比如作为函数返回值、函数参数等。
- 频繁调用场合并不适合new,就像new申请和释放内存一样。
c++用new与不用new创建对象的区别
C++之对象的赋值与复制(拷贝构造函数)
char为1个字节
- int 4
- double 8
- float 4
位运算常用技巧
- x & (1 << m) = 1 (若第m+1位为1)否则为0
- 1.获得int型最大值
int getMaxInt(){
return (1 << 31) - 1;//2147483647, 由于优先级关系,括号不可省略
}
- 获得int型最小值
int getMinInt(){
return 1 << 31;//-2147483648
}
- 乘以2的m次方
int mulTwoPower(int n,int m){//计算n*(2^m)
return n << m;
}
5.除以2的m次方
int divTwoPower(int n,int m){//计算n/(2^m)
return n >> m;
}
- 判断一个数的奇偶性
boolean isOddNumber(int n){
return (n & 1) == 1;
}
- 判断符号是否相同
boolean isSameSign(int x, int y){ //有0的情况例外
return (x ^ y) >= 0; // true 表示 x和y有相同的符号, false表示x,y有相反的符号。
}
- 计算2的n次方
int getFactorialofTwo(int n){//n > 0
return 2 << (n-1);//2的n次方
}
- 判断一个数是不是2的幂
boolean isFactorialofTwo(int n){
return n > 0 ? (n & (n - 1)) == 0 : false;
/*如果是2的幂,n一定是100... n-1就是1111....
所以做与运算结果为0*/
}
- 对2的n次方取余
int quyu(int m,int n){//n为2的次方
return m & (n - 1);
/*如果是2的幂,n一定是100... n-1就是1111....
所以做与运算结果保留m在n范围的非0的位*/
}
- 32位二进制位变成十进制数
int count[32]={1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0}
for(int i = 0; i < 32; i++) {
res <<= 1;
res |= counts[31 - i];
}
乘法溢出问题
- 优先使用除法代替
- 使用 long long。先强转!
long long r = (long long)mid*mid;
cout<<"r的值为:"<<r<<endl;
long long l = mid *mid;
cout<<"l的值为:"<<l<<endl;
r的值为:288206741431210000
Line 14: Char 31: runtime error: signed integer overflow: 536848900 * 536848900 cannot be represented in type 'int' (solution.cpp)
- 计算r时,第一个mid被强转成longlong,变成两个longlong相乘的结果存入longlong。
- 计算l时,两个int相乘的结果存入longlong,但是由于int相乘溢出报错。
用++i替换do while
while (l < r && nums[r] == nums[--r]);
```cpp
do
{
r--;
} while (r > l && nums[r] == nums[r + 1]);