- 一:STL
- 1:vector的三种遍历方式。
- 2:vector中的auto函数:(重点)
- (1):让编译器自己去推断类型,并且遍历
- (2)为了验证猜想,用最简单的int型数组试验一下。
- (3)试试double类型能否实现遍历
- (4)试试long long 类型
- (5)结论:auto只是为了让编译器自己识别数据类型,常与冒号一起使用,实现遍历,其他数据类型也可以,但是必须准确。
- 3:push_back()
- 4:pop_back()
- 1:vector的三种遍历方式。
- 二:位运算
- 1:& 运算
- 2:|或运算
- 3:~非
- 4:异或
- 5:左移
- 6:右移
- 7:用代码表示左移右移:
- (1):取出数字13的第二位数字(二进制的13)
- (2)取出想要位子上的数字方法:
- (3)输出二进制数字所有的位上的值:
- 8: -a等于 ~a+1
- 三:常用库函数
- 1:reverse函数 翻转(非常重要)
- 小插曲:验证了一下数组越界的访问会出现什么错误:
- 完美验证了计算机组成原理的重要性。
- 2:unique函数 去重
- 一个很强的函数,erase
- 3:random_shuffle 函数随机打乱
- 特别注意的是time(0)是个固定用法
- 4:sort函数(从小到大排序)
- 快速排序函数中的cmp实现
- sort函数自定义cmp返回值从大到小排
- 5:sort排结构体+运算符重载+传参
#include
#include
using namespace std;
int main()
{
vector<int>a({1,2,3});
for(int i=0;i<a.size();i++)cout << a[i]<<' ';//和数组一样的遍历方式
cout << endl;
for(auto i=a.begin();i!=a.end();i++) cout << *i<< ' ';//使用迭代器遍历,迭代器相当于地址。
cout << endl;
for(int x:a)cout << x << ' ';//和string一样
cout << endl;
return 0;
}
2:vector中的auto函数:(重点)
(1):让编译器自己去推断类型,并且遍历
定义了一个x变量,但是不确定什么类型,为了方便,就用auto,让编译器自己去猜,x:a 是把a中的元素遍历并送到x中。
通过结果也可以看出来,输出的是1234。
证明 x : a 确实是遍历了,把a中的元素送到了x里面。
如果auto是类型,那么 冒号:才代表遍历
经过尝试:
得出结论,为什么auto和冒号: 经常在一起使用,原因可能就是遍历的时候为了方便,不用去考虑类型了,只用把冒号后面想要遍历的一个字符串或者数组或者其他的类型,遍历到冒号前面的变量中,就不用自己再去判断类型了,很方便。
换个类型也一样
3:push_back()
在尾部插入一个元素
删除vector a的最后一个元素
调用两次:
计算机组成原理中有详细阐述。
位运算中有 & 与,| 或, ~非 ,^异或, << 左移,>> 右移
类似于乘法, 只有全1才是1,只要有一个0,那么相 与 的结果就是0.
2:|或运算两个数或者多个数,只要有一个1,那么结果就是1,类似于加法
3:~非就是取反
4:异或两个数不同才为1,相同为0。
左移右移比较重要。
相当于把二进制数向左移动一位,右边补零
0110 左移一位 01100 左移就是相当于乘2,左移k位就是乘以2的k次方
二进制数向右移动一位,0110 右移一位 0011
右移相当于除2,右移n位就是除以2的n次方。
二进制的13是 1101 那么第二位数字应该是1 我们用代码测试一下
为什么可以这样? 因为与上1可以取出来个位数字,即取得二进制数字表示中自己想要的数字。
想要去除任意一个位子上的数字,我们都可以采用右移n位,然后与1来计算。
如果结果为1,就是1,与1结果为0就是0.这样做可以取出相应位子上的数字。
如果想要取出来二进制数的第k位数字,那么就先 让a右移k 再与上1.
(3)输出二进制数字所有的位上的值:以13为例
8: -a等于 ~a+1
可以看出来 在C++中,-a等于~a+1
起到翻转的作用。
可以翻转vector也可以翻转数组也可以翻转链表
可以看到,我们reverse的a+6 超出了定义的数组的长度5 ,就出现了一个相对来说很大的数字,32767 这是多少? 2的15次方等于32768 32767就等于2^15 -1 为什么减去1? 在计算机组成原理中,二进制数的范围就是-2的15次方到 +2的十五次方-1。
因为中间有一个0。
从这里我们又可以知道,为什么是15次方? 看来在该编译器中,数组的产长度是 4 个4位
这个是全1的情况,也就是16个1 代表2的十五次方(这里不是补码的意思,如果是补码的话,最开始的1代表负号,也就是最左边的,但是我们在这里只表示数字的大小)。
正确的遍历的范围应该是a,a+5
2:unique函数 去重对数组的一个判重。
m 调用unique函数 去重 随后输出m,m就是去重之后数组中的不同的值的个数。
unique的参数类型,第一个参数是begin 第二个是end。
和reverse参数类型一样。
去重vector试一下:
这个函数的作用是
前一个参数是unique函数,调用完unique函数后,相当于去重了,然后第二个参数是end。
表示结束的位置,这样这样就能从数组中去重过的位置,遍历到末尾,把这一段的元素删除掉。
这两句话的意思是:
先把a.begin() 和a.end() 之间元素判个重然后放在数组的最开头的位置,然后再把后面多余的部分删掉。
这样做完之后,a里面的vector就会变成1 2 3 4 代码也证实了这一点。
用法与reverse相同,用在生成数据的时候。
用法:打乱顺序。
用法:函数里面的参数,第一个是a.begin() 第二个就是a.end()
一个开头一个结尾。
即使调用了random_shuffle函数,但是多次调用的结果还是一样,即使顺序乱了,但是每次的结果是一样的。
为什么?
这是因为random_shuffle 函数用到了随机种子这个概念。
srand();
随机种子默认是0. 所以即使打乱了顺序,但是由于随机种子是不变的,所以打乱的顺序也是不变的。
每次运行结果不一样,一般可以把时间传进去,当作一个随机种子。
由于运行时间不一样,所以随机种子不一样,所以结果就会不一样。
time(0)是返回当前到1970年1月1号的秒数。
代码如图:
可以明显的看出来,每次的结果都不一样。
但是,两个必须搭配着用才有用处。
注释掉random_shuffle 后,就不能使结果随机化了。
搭配函数使用,不用time(0)行不行?换成其他数据可以吗?
看来是不行的,time(0)是个固定用法
快速排序函数,能够快速地排序一个乱序数组。
特别注意的是,当数据量特别大的时候,推荐用归并排序。
关于sort函数的实现可以看我前一段时间的一篇文章
快速排序算法
sort默认从小到大排序,如果想从大到小按顺序排,需要加一个参数。
可以看出来,第二句输出从1 2 3 4 5 变成了 5 4 3 2 1。
升序变降序了。
看我这一篇文章即可
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)