函数lower_bound()(没找到就返回最大下标的下一个)
在first和last中的前闭后开区间进行二分查找(所以要先排序),返回大于或等于>=val的第一个元素位置。如果所有元素都小于val,则返回last的位置(地址,即指针)可自定义比较函数,但只有与sort一起用从大到小才能求出第一个<=k的数
举例如下:
一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标
则
pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。
pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。
pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。
所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~
返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置
手动实现:
//草稿纸演算一下可知
while(l<r)
{
mid=(l+r)/2;
if(a[midm]>=m)
r=mid;
else
l=mid+1;
}
cout<<l;
equal_range
是C++ STL中的一种二分查找的算法,试图在已排序的[first,last)中寻找value,它返回一对迭代器i和j,其中i是在不破坏次序的前提下,value可插入的第一个位置(亦即lower_bound),j则是在不破坏次序的前提下,value可插入的最后一个位置(亦即upper_bound),因此,[i,j)内的每个元素都等同于value,而且[i,j)是[first,last)之中符合此一性质的最大子区间
如果以稍许不同的角度来思考equal_range,我们可把它想成是[first,last)内"与value等同"之所有元素形成的区间A,由于[fist,last)有序(sorted),所以我们知道"与value等同"之所有元素一定都相邻,于是,算法lower_bound返回区间A的第一个迭代器,算法upper_bound返回区间A的最后一个元素的下一个位置,算法equal_range则是以pair的形式将两者都返回
即使[fist,last)并未含有"与value等同"之任何元素,以上叙述仍然合理,这种情况下,"与value等同"之所有元素形成的,其实是一个空区间,在不破坏次序的情况下,只有一个位置可以插入value,而equal_range所返回的pair,其第一和第二(都是迭代器)皆指向该位置。
- // map::equal_elements
- #include <iostream>
- #include <map>
- using namespace std;
- int main ()
- {
- map<char,int> mymap;
- pair<map<char,int>::iterator,map<char,int>::iterator> ret;
- mymap['a']=10;
- mymap['b']=20;
- mymap['c']=30;
- ret = mymap.equal_range('b');
- cout << "lower bound points to: ";
- cout << ret.first->first << " => " << ret.first->second << endl;
- cout << "upper bound points to: ";
- cout << ret.second->first << " => " << ret.second->second << endl;
- return 0;
- }
运行结果:
- lower bound points to: 'b' => 20
- upper bound points to: 'c' => 30
tolower()
功能是把字母字符转换成小写,非字母字符不做出处理。和函数int _tolower( int c )功能一样
C++容器的insert()函数
有以下三种用法: 最终*it=val;
//用法1:在指定位置it前“插入”值为val的元素,返回指向这个元素的迭代器,
iterator insert( iterator it, const TYPE &val );
//用法2:在指定位置it前“插入”num个值为val的元素
void insert( iterator it, size_type num, const TYPE &val );
//用法3:在指定位置it前“插入”区间[start, end)的所有元素.
void insert( iterator it, input_iterator start, input_iterator end );
举例:
//创建一个vector,置入字母表的前十个字符
vector <char> charV;
for( int i=0; i < 10; i++ )
charV.push_back( i + 65 );
//插入四个C到vector中
vector <char>::iterator it = charV.begin();
charV.insert( it, 4, 'C' );
//显示vector的内容
for( it = charV.begin(); it != charV.end(); it++ )
cout < < *it;
这段代码将显示:
CCCCABCDEFGHIJ
memcpy()
原型:
void *memcpy(void *dest, constvoid *src, size_t n);
需要的头文件:
#include<string.h>
用法:
memcpy函数是内存拷贝函数,功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。因为这个函数是直接操作内存的.
memcpy(b, a, sizeof(a));
【C++】fill函数,fill与memset函数的区别
-
memset函数
- 按照字节填充某字符
- 在头文件
<cstring>
里面 - 对于非字符不要随便用,用来清零可以,对0与-1可以赋值一维二维数组,其他的不对 a[n],b[n][n],则memset(a,0,sizeof(a)), memset(b,0,sizeof(b))
- 可以对任意类型清零(包括类,而fill不行)
-
fill函数
- 按照单元赋值,将一个区间的元素都赋同一个值
- 在头文件
<algorithm>
里面
-
如果是字符数组的话,memset可以随便用,但是如果是其他类型的数组,一般只用来清零,如果是填充数据就不合适了,如:
memset(a, 1, sizeof(a));
想用这个来把a所有元素设置为1,是不成功的,为什么呢?因为memset函数每次填充的数据长度为一个字节,即为0x01,而a的一个元素长度为4个字节,即0x00000000,如果把0x01填充进去,则填充的结果是0x01010101,而不是我们期待的0x00000001,所以是不合适的,但是用来清零真是一级棒! -
因为memset函数按照字节填充,所以一般memset只能用来填充char型数组,(因为只有char型占一个字节)如果填充int型数组,除了0和-1,其他的不能。因为只有00000000 = 0,-1同理,如果我们把每一位都填充“1”,会导致变成填充入“11111111”
-
而fill函数可以赋值任何,而且使用方法特别简便:
- fill(arr, arr + n, 要填入的内容);
- 例如:
#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
int arr[10];
fill(arr, arr + 10, 2);
return 0;
}
- vector也可以:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main(){
vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
fill(v.begin(), v.end(), -1);
return 0;
}
- 而memset的使用方法是:
#include <iostream> #include <cstring> using namespace std; int main(){ int a[20]; memset(a, 0, sizeof a); return 0; }
count函数
统计某一值在一定范围内出现的次数(函数模板)Count appearances of value in range
函数原型
1 2 3 4 5 6 7 |
|
输入参数
first:查询的起始位置,为一个迭代器 last: 查询的结束位置,为一个迭代器
返回值
通过比较是否等于 val 返回[first,last]与 val相等的数值的个数。
关于全排列 next_permutation() 函数的用法
这是一个c++函数,包含在头文件<algorithm>里面,下面是基本格式。
复制代码
1 int a[];
2 do{
3
4 }while(next_permutation(a,a+n));
复制代码
下面的代码可产生1~n的全排列。
复制代码
#include <stdio.h>
#include <algorithm>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)&&n){
int a[1000];
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);//可以自行测试一下删除后的结果
do{
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}while(next_permutation(a,a+n));
}
return 0;
}
复制代码
例如输入
3
1 0 2
如果有sort()
输出为
0 1 2
0 2 1
1 0 2
1 2 0
2 0 1
2 1 0
若无
则输出为
1 0 2
1 2 0
2 0 1
2 1 0
可以发现少了许多种组合方法。
不过,仔细比较各种组合方法和有无sort()的输出,可以发现函数next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序。
C++中rotate函数(好像以前版本时间复杂度很低,随机迭代器效率很低)
int a[7]={1,2,3,4,5,6,7};
rotate(a,a+1,a+7);
for(int i=0;i<7;++i)
cout<<a[i]<<" ";
rotate(a,a+1,a+7);
for(int i=0;i<7;++i)
cout<<a[i]<<" ";
//ooutput:2 3 4 5 6 7 1
3 4 5 6 7 1 2
三个参数(first,middle,last)
first,last
分别指向序列中初始及末尾位置的正向迭代器(Forward Iterators)。这个范围即 [first,last) ,包括 first 到 last 间的所有元素,包括 first 指向的元素,但不包括 last 指向的元素。
middle
指向范围 [first,last) 中某个元素的正向迭代器。
floor函数:向下取整
e.g:
floor(3.14) = 3.0
floor(9.999999) = 9.0
floor(-3.14) = -4.0
floor(-9.999999) = -10
T accumulate(first,last,T init)
在#include <numeric>
计算初始值为init,从first到last所有数的累加和