结合NYOJ的STl分类练习和大神们的博客,总结了一下stl的学习。所有来源均已注明。提供全文下载地址:https://yunpan.cn/cBhkAUIPfTWCn 访问密码 5807
STL之stack
关于栈的总结:
栈(stack)
栈(statck)这种数据结构在计算机中是相当出名的。栈中的数据是先进后出的(First In Last Out, FILO)。栈只有一个出口,允许新增元素(只能在栈顶上增加)、移出元素(只能移出栈顶元素)、取得栈顶元素等操作。在STL中,栈是以别的容器作为底部结构,再将接口改变,使之符合栈的特性就可以了。因此实现非常的方便。下面就给出栈的函数列表和VS2008中栈的源代码,在STL中栈一共就5个常用操作函数(top()、push()、pop()、 size()、empty() ),很好记的。
可以看出,由于栈只是进一步封装别的数据结构,并提供自己的接口,所以代码非常简洁,如果不指定容器,默认是用deque来作为其底层数据结构的(对deque不是很了解?可以参阅《STL系列之一 deque双向队列》)。下面给出栈的使用范例:
//栈 stack支持 empty() size() top() push() pop()
// by MoreWindows(http://blog.csdn.net/MoreWindows)
#include <stack>
#include <vector>
#include <list>
#include <cstdio>
using namespace std;
int main()
{
//可以使用list或vector作为栈的容器,默认是使用deque的。
stack<int, list<int>> a;
stack<int, vector<int>> b;
int i;
//压入数据
for (i = 0; i < 10; i++)
{
a.push(i);
b.push(i);
}
//栈的大小
printf("%d %d\n", a.size(), b.size());
//取栈项数据并将数据弹出栈
while (!a.empty())
{
printf("%d ", a.top());
a.pop();
}
putchar('\n');
while (!b.empty())
{
printf("%d ", b.top());
b.pop();
}
putchar('\n');
return 0;
}
比较完整的栈的总结:http://blog.csdn.net/morewindows/article/details/6950881
关于栈的题:
NYOJ括号配对问题:题目2 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=2
题目描述:
括号配对问题
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
现在,有一行括号序列,请你检查这行括号是否配对。
输入
第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
样例输入
3
[(])
(])
([[]()])
样例输出
No
No
Yes
来源
网络
上传者
naonao
AC代码:
#include <iostream>
#include <stack>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int T;
cin>>T;
stack<char>ss;
char sss[10010];
while(T--)
{
scanf("%s",sss);
int i,len;
len=strlen(sss);
ss.push(sss[0]);
for(i=1; i<len; i++)
{
if(ss.empty()) ss.push(sss[i]);
else
{
if((ss.top()=='['&&sss[i]==']')||(ss.top()=='('&&sss[i]==')'))
ss.pop();
else ss.push(sss[i]);
}
}
if(ss.empty()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
while(!ss.empty())
{
ss.pop();
}
}
return 0;
}
NYOJ汉诺塔(三)题目93 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=93
题目描述:
汉诺塔(三)
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
现在我们把三根针编号为1,2,3。
所有的金片在初始时都在1号针上,现在给你的任务是判断一系列的指令过程中,是否会出现非法的指令。
而非法指令有以下两种情况:
1、某个针上已经没有金片了,但是指令依然要求从该处移动金片到其它针上。
2、把一个大的金片移动到了小的金片上。
输入
第一行输入一个整数N表示测试数据的组数(N<10)
每组测试数据的第一行有两个整数P,Q(1<P<64,1<Q<100),分别表示汉诺塔的层数与随后指令的条数
随后的Q行,每行都输入两个整数a,b,(1<=a,b<=3)表示一条指令。
指令1 2表示把1号针最上面的金片移动到2号针最上面。
数据保证a,b不会相同。
输出
如果存在非法指令,请输出illegal
不存在非法指令则输出legal
样例输入
3
2 1
1 2
3 3
1 2
1 3
3 2
2 1
2 1
样例输出
legal
illegal
illegal
来源
[张云聪]原创
上传者
张云聪
AC代码:
#include <iostream>
#include <stack>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int T;
cin>>T;
stack<int> aa[4];
while(T--)
{
while(!aa[1].empty())
aa[1].pop();
while(!aa[2].empty())
aa[2].pop();
while(!aa[3].empty())
aa[3].pop();
int p,q,i,j,from,to;
cin>>p>>q;
for(i=p;i>=1;i--)
aa[1].push(i);
int k=1;
for(j=0;j<q;j++)
{
cin>>from>>to;
if(aa[from].empty()) //如果要移动的金针为空则为非法指令1
{
k=0;break;
}
else if(!aa[to].empty()&&aa[to].top()<aa[from].top()) //如果被移动到的金针的顶端元素小于被移动的那个则为非法指令2
{
k=0;break;
}
aa[to].push(aa[from].top());
aa[from].pop();
}
if(k==1) cout<<"legal"<<endl;
else cout<<"illegal"<<endl;
}
return 0;
}
STL之sort和qsort
一、sort函数
#include sort(s,s+m,cmp);
qsort 的函数
#include
struct angle{
int a,b,c;
};
(sort实现结构体多级排序,升序)
bool cmp(angle x,angle y)
{ if(x.a!=y.a) return x.a<y.a;
else if(x.b!=y.b) return x.b<y.b;
else if(x.c!=y.c) return x.c<y.c;
}
(qsort实现结构体多级排序,升序)
int cmp(const void*p,const*q)
{ angle *x=(angle*)p;
angle *y=(angle *)q;
if(x->a!=y->a) return x->a>y->a;
else if(x->b!=y->b) return x->b >y->b;
else if(x->c!=y->c) return x->c >y->c;
}
比较详细的sort和qsort总结: http://blog.csdn.net/m6830098/article/details/17456263
qsort:
函数原型:void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
函数作用:使用compar函数来对 从base地址开始的num 个元素(第二个参数)来进行排序,compar决定排序的方式。函数不返回任何值,修改了base指针指向的数组的内容。
函数参数:
• base 指向要排序数组的第一个对象,被转换为一个void*指针.
• num 无符号整形变量,从base指针指向的对象开始有多少个对象需要排序。
• size 无符号整形变量,代表数组中每个元素的大小
• compar 指向一个比较两个元素大小的函数。这个函数将会被qsort函数重复的调用来比较两个元素的大小,它的定义方式是固定的。
compar 的定义方式应该是 int compar (const void* p1, const void* p2); 需要两个参数,都会被转化为const void*,会根据返回值的大小来决定排序的方式。
如果返回值 <0,则按照从小到大排序,如果返回值大于0,则从大到小排序,返回值等于0,则应该是按从小到大排序。
Code Example:
#include <iostream>
#include <string.h>
using namespace std;
int cmp (const void * a, const void * b)
{
if ( *(int*)a < *(int*)b )
return 1;
else
return -1;
}
int main(int argc, const char * argv[])
{
int a[ ] = {5, 211111111, -211111111, 7, 8, 2};
qsort(a, 6, sizeof( a[ 0 ] ), cmp);
for( int i = 0; i < 6; i++ )
cout << a[ i ] << " ";
cout << endl;
return 0;
}
时间复杂度为 nlog2(n).
这里有一个问题,cmp函数最好不要写成这个样子:
int cmp (const void * a, const void * b)
{
return *( int * ) a - *( int * )b;
}
如果直接写成这个样子的话,当排序的数组值很大的时候,有可能会造成溢出的问题
结构体可以设定多级排序:
#include <iostream>
#include <string.h>
using namespace std;
struct Student{
int number;
int age;
char s;
};
int cmp (const void * a, const void * b)
{
struct Student * p = (Student *) a;
struct Student * q = (Student *) b;
if( p -> number < q -> number )
return -1;
else if ( p ->number > q -> number )
return 1;
else
return ( p -> age < q -> age ) ? -1 : 1;
}
int main(int argc, const char * argv[])
{
Student A[ 5 ];
A[ 0 ] = { 5,8,'c'};
A[ 1 ] = { 8,8,'c'};
A[ 2 ] = { 6,6,'c'};
A[ 3 ] = { 6,8,'c'};
A[ 4 ] = { 2,8,'c'};
qsort( A, 5, sizeof(Student), cmp );
for( int i = 0; i < 5; i++ )
cout << A[ i ].number << " " << A[ i ].age << " " << A[ i ].s << endl;
return 0;
}
Sort
sort 排序算法是STL中提供给我们的。STL中提供了好多个排序的算法
1. 所有STL sort算法函数的名字列表:
函数名 功能描述
sort 对给定区间所有元素进行排序
stable_sort 对给定区间所有元素进行稳定排序
partial_sort 对给定区间所有元素部分排序
partial_sort_copy 对给定区间复制并排序
nth_element 找出给定区间的某个位置对应的元素
is_sorted 判断一个区间是否已经排好序
partition 使得符合某个条件的元素放在前面
stable_partition 相对稳定的使得符合某个条件的元素放在前面
如果你需要自己定义比较函数,你可以把定义好的仿函数作为参数传入,每种算法都支持比较函数。
七种 qsort 排序方法 :http://blog.csdn.net/rattles/article/details/5510919
NYOJ一种排序:题目8 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=8
一种排序
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复;还知道这个长方形的宽和长,编号、长、宽都是整数;现在要求按照一下方式排序(默认排序规则都是从小到大);
1.按照编号从小到大排序
2.对于编号相等的长方形,按照长方形的长排序;
3.如果编号和长都相同,按照长方形的宽排序;
4.如果编号、长、宽都相同,就只保留一个长方形用于排序,删除多余的长方形;最后排好序按照指定格式显示所有的长方形;
输入
第一行有一个整数 0<n<10000,表示接下来有n组测试数据;
每一组第一行有一个整数 0<m<1000,表示有m个长方形;
接下来的m行,每一行有三个数 ,第一个数表示长方形的编号,
第二个和第三个数值大的表示长,数值小的表示宽,相等
说明这是一个正方形(数据约定长宽与编号都小于10000);
输出
顺序输出每组数据的所有符合条件的长方形的 编号 长 宽
样例输入
1
8
1 1 1
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
样例输出
1 1 1
1 2 1
1 2 2
2 1 1
2 2 1
来源
经典题目
上传者
iphxer
AC代码(sort):
#include <iostream>
#include <algorithm>
using namespace std;
//练习sort
struct my_struct
{
int num,length,wideth;
};
bool cmp(my_struct a,my_struct b)
{
if(a.num!=b.num) return a.num<b.num;
else if(a.length!=b.length) return a.length<b.length;
else if(a.wideth!=b.wideth) return a.wideth<b.wideth;
}
int main()
{
int T;
cin>>T;
my_struct aa[1010];
while(T--)
{
int n;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>aa[i].num>>aa[i].length>>aa[i].wideth;
int k;
if(aa[i].length<aa[i].wideth)
{
k=aa[i].length;
aa[i].length=aa[i].wideth;
aa[i].wideth=k;
}
}
sort(aa,aa+n,cmp);
for(int i=0; i<n; i++)
if(aa[i].num!=aa[i+1].num||aa[i].length!=aa[i+1].length||aa[i].wideth!=aa[i+1].wideth)
cout<<aa[i].num<<" "<<aa[i].length<<" "<<aa[i].wideth<<endl;
}
}
AC代码(qsort):
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
//学习STL中的qsort
struct my_struct
{
int num,length,wideth;
};
int cmp(const void*a,const void*b)
{
my_struct* x=(my_struct *)a;
my_struct* y=(my_struct*) b;
if(x->num!=y->num) return x->num > y->num;
else if(x->length!=y->length) return x->length > y->length;
else if(x->wideth!=y->wideth) return x->wideth > y->wideth;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
my_struct aa[1010];
for(int i=0; i<n; i++)
{
cin>>aa[i].num>>aa[i].length>>aa[i].wideth;
int k;
if(aa[i].length<aa[i].wideth)
{
k=aa[i].length;
aa[i].length=aa[i].wideth;
aa[i].wideth=k;
}
}
qsort(aa,n,sizeof(aa[0]),cmp);
for(int i=0; i<n; i++)
if(aa[i].num!=aa[i+1].num||aa[i].length!=aa[i+1].length||aa[i].wideth!=aa[i+1].wideth)
cout<<aa[i].num<<" "<<aa[i].length<<" "<<aa[i].wideth<<endl;
}
return 0;
}
NYOJ ASII码排序:题目4 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=4
ASCII码排序
时间限制:3000 ms | 内存限制:65535 KB
难度:2
描述
输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符。
输入
第一行输入一个数N,表示有N组测试数据。后面的N行输入多组数据,每组输入数据都是占一行,有三个字符组成,之间无空格。
输出
对于每组输入数据,输出一行,字符中间用一个空格分开。
样例输入
2
qwe
asd
样例输出
e q w
a d s
来源
网络
上传者
naonao
AC代码(qsort):
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
//学习STL中的qsort
int cmp(const void*a,const void *b)
{
char *x=(char*)a;
char *y=(char*)b;
return *x>*y;//注意这里不要写成>y
}
int main()
{
int T;
cin>>T;
getchar();
while(T--)
{
char a[3];
cin>>a[0]>>a[1]>>a[2];
qsort(a,3,sizeof(a[0]),cmp);
for(int i=0; i<3; i++)
{
cout<<a[i];
if(i==2) cout<<"\n";
else cout<<" ";
}
}
return 0;
}
AC代码(sort):
#include <iostream>
#include <algorithm>
using namespace std;
//练习sort
bool cmp(char a,char b)
{
return a<b;
}
int main()
{
int T;
cin>>T;
while(T--)
{
char ss[3];
cin>>ss[0]>>ss[1]>>ss[2];
sort(ss,ss+3,cmp);
cout<<ss[0]<<" "<<ss[1]<<" "<<ss[2]<<endl;
}
return 0;
}
NYOJ三个数从小到大排序:题目41 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=41
三个数从小到大排序
时间限制:3000 ms | 内存限制:65535 KB
难度:0
描述
现在要写一个程序,实现给三个数排序的功能
输入
输入三个正整数
输出
给输入的三个正整数排序
样例输入
20 7 33
样例输出
7 20 33
来源
[张洁烽]原创
上传者
张洁烽
AC代码(sort):
#include <iostream>
#include <algorithm>
using namespace std;
//练习sort
bool cmp(int a,int b)
{
return a<b;
}
int main()
{
int a[3];
while(cin>>a[0]>>a[1]>>a[2])
{
sort(a,a+3,cmp);
for(int i=0; i<3; i++)
{
cout<<a[i];
if(i==2) cout<<endl;
else cout<<" ";
}
}
return 0;
}
AC代码(qsort):#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
//学习STL中的qsort
int cmp(const void*a,const void *b)
{
int *x=(int *)a;
int *y=(int *)b;
return *x>*y;
}
int main()
{
int aa[3];
while(cin>>aa[0]>>aa[1]>>aa[2])
{
qsort(aa,3,sizeof(aa[0]),cmp);
cout<<aa[0]<<" "<<aa[1]<<" "<<aa[2]<<endl;
}
return 0;
}
STL之max_element 和min_elemen:
引用:http://blog.csdn.net/zwj1452267376/article/details/46777235
min_element()和max_element
头文件:#include
作用:返回容器中最小值和最大值。max_element(first,end,cmp);其中cmp为可选择参数!
代码例子:
include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{
return a<b;
}
int main()
{
int num[]={2,3,1,6,4,5};
cout<<"最小值是 "<<*min_element(num,num+6)<<endl;
cout<<"最大值是 "<<*max_element(num,num+6)<<endl;
cout<<"最小值是 "<<*min_element(num,num+6,cmp)<<endl;
cout<<"最大值是 "<<*max_element(num,num+6,cmp)<<endl;
return 0;
}
STL之nth_element取容器中第n大的值:
http://blog.csdn.net/zwj1452267376/article/details/46779359
nth_element()函数
头文件:#include
作用:nth_element作用为求第n大的元素,并把它放在第n位置上,下标是从0开始计数的,也就是说求第0小的元素就是最小的数。
如:a[start,end]元素区间。排序后a[n]就是数列中第n+1大的数(下标从0开始计数)。要注意的是a[start,n),
a[n,end]内的大小顺序还不一定。只能确定a[n]是数列中第n+1大的数。当然a[start,n)中的数肯定不大于
a[n,end]中的数。
注意:nth_element()函数仅仅是将第n大的数排好了位置,并不返回值。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a[]={1,3,4,5,2,6,8,7,9};
int i;
cout<<"数列如下:"<<endl;
for(i=0;i<9;i++)
cout<<a[i]<<" ";
nth_element(a,a+5,a+9);
cout<<endl<<"输出第五大的数: "<<a[4]<<endl; //注意下标是从0开始计数的
return 0;
}
NYOJ五个数求最值:题目31 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=31
5个数求最值
时间限制:1000 ms | 内存限制:65535 KB
难度:1
描述
设计一个从5个整数中取最小数和最大数的程序
输入
输入只有一组测试数据,为五个不大于1万的正整数
输出
输出两个数,第一个为这五个数中的最小值,第二个为这五个数中的最大值,两个数字以空格格开。
样例输入
1 2 3 4 5
样例输出
1 5
来源
C语言课本第四章第一题
上传者
张云聪
AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
bool cpm(int a,int b)
{
return a<b;
}
int main()
{
int aa[5];
for(int i=0;i<5;i++)
cin>>aa[i];
cout<<*min_element(aa,aa+5)<<" "<<*max_element(aa,aa+5)<<endl;//注意要加*,不不然返回的是地址
return 0;
}
STL之优先队列:
http://www.cnblogs.com/heqinghui/archive/2013/07/30/3225407.html
STL 中优先队列的使用方法(priority_queu)
基本操作:
empty() 如果队列为空返回真
pop() 删除对顶元素
push() 加入一个元素
size() 返回优先队列中拥有的元素个数
top() 返回优先队列对顶元素
在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。
使用方法:
头文件:
#include <queue>
声明方式:
1、普通方法:
priority_queueq;
//通过操作,按照元素从大到小的顺序出队
2、自定义优先级:
struct cmp
{
operator bool ()(int x, int y)
{
return x > y; // x小的优先级高
//也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
}
};
priority_queue<int, vector<int>, cmp>q;//定义方法
//其中,第二个参数为容器类型。第三个参数为比较函数。
3、结构体声明方式:
struct node
{
int x, y;
friend bool operator < (node a, node b)
{
return a.x > b.x; //结构体中,x小的优先级高
}
};
<span style="font-size:24px;">priority_queue<node>q;//定义方法</span>
//在该结构中,y为值, x为优先级。
//通过自定义operator<操作符来比较元素中的优先级。
//在重载”<”时,最好不要重载”>”,可能会发生编译错误
struct cmp
{
bool operator()(const Node &a,const Node &b)
{
return a.ubound<b.ubound;
}
};
priority_queue<Node,vector<Node>,cmp> activeNodes;
NYOJ懒省事的小明:题目55 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=55
懒省事的小明
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
小明很想吃果子,正好果园果子熟了。在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。小明决定把所有的果子合成一堆。 因为小明比较懒,为了省力气,小明开始想点子了:
每一次合并,小明可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。小明在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以小明在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以小明总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
输入
第一行输入整数N(0<N<=10)表示测试数据组数。接下来每组测试数据输入包括两行,第一行是一个整数n(1<=n<=12000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
输出
每组测试数据输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。
样例输入
1
3
1 2 9
样例输出
15
AC代码:
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int aa[20010];
priority_queue<int,vector<int>,greater<int> >ss;//greater表示先出最小的,换成less则先出大的
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
long long ans=0;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>aa[i];
ss.push(aa[i]);
}
while(ss.size()!=1)
{
int x,y;
x=ss.top();
ss.pop();
y=ss.top();
ss.pop();
x+=y;
ans+=x;
ss.push(x);
}
while(!ss.empty())
ss.pop();
cout<<ans<<endl;
}
return 0;
}
STL之set
http://www.cnblogs.com/BeyondAnyTime/archive/2012/08/13/2636375.html
1.关于set
C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入、排序、删除、查找等。让用户在STL使用过程中,并不会感到陌生。
关于set,必须说明的是set关联式容器。set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。
2.set中常用的方法
begin() ,返回set容器的第一个元素
end() ,返回set容器的最后一个元素
clear() ,删除set容器中的所有的元素
empty() ,判断set容器是否为空
max_size() ,返回set容器可能包含的元素最大个数
size() ,返回当前set容器中的元素个数
rbegin ,返回的值和end()相同
rend() ,返回的值和rbegin()相同
count() 用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。
equal_range() ,返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。具体这个有什么用途我还没遇到过~~~
实例:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> s;
set<int>::iterator iter;
for(int i = 1 ; i <= 5; ++i)
{
s.insert(i);
}
for(iter = s.begin() ; iter != s.end() ; ++iter)
{
cout<<*iter<<" ";
}
cout<<endl;
pair<set<int>::const_iterator,set<int>::const_iterator> pr;
pr = s.equal_range(3);
cout<<"第一个大于等于 3 的数是 :"<<*pr.first<<endl;
cout<<"第一个大于 3的数是 : "<<*pr.second<<endl;
return 0;
}
NYOJ找球号(一):题目86 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=86
找球号(一)
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
在某一国度里流行着一种游戏。游戏规则为:在一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,现在说一个随机整数k(0<=k<=100000100),判断编号为k的球是否在这堆球中(存在为"YES",否则为"NO"),先答出者为胜。现在有一个人想玩玩这个游戏,但他又很懒。他希望你能帮助他取得胜利。
输入
第一行有两个整数m,n(0<=n<=100000,0<=m<=1000000);m表示这堆球里有m个球,n表示这个游戏进行n次。
接下来输入m+n个整数,前m个分别表示这m个球的编号i,后n个分别表示每次游戏中的随机整数k
输出
输出"YES"或"NO"
样例输入
6 4
23 34 46 768 343 343
2 4 23 343
样例输出
NO
NO
YES
YES
AC代码:
#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
using namespace std;
const int maxn=1000010;
int aa[maxn];
int main()
{
set<int> ss;
int m,n;
while(cin>>m>>n)
{
for(int i=0; i<m; i++)
{
cin>>aa[i];
ss.insert(aa[i]);
}
for(int j=0; j<n; j++)
{
cin>>aa[j];
if(ss.find(aa[j])==ss.end())
cout<<"NO\n";
else cout<<"YES\n";
}
}
return 0;
}
STL之map:
C++ map的基本操作和使用Live新浪博客
http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html
C++学习之map类型 - liucanrui的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/liucanrui/article/details/6591029
Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作!
1. map最基本的构造函数;
map<string , int >mapstring; map<int ,string >mapint;
map<sring, char>mapstring; map< char ,string>mapchar;
map<char ,int>mapchar; map<int ,char >mapint;
2. map添加数据;
map<int ,string> maplive;
1.maplive.insert(pair<int,string>(102,"aclive"));
2.maplive.insert(map<int,string>::value_type(321,"hai"));
3, maplive[112]="April";//map中最简单最常用的插入添加!
3,map中元素的查找:
find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。
map<int ,string >::iterator l_it;;
l_it=maplive.find(112);
if(l_it==maplive.end())
cout<<"we do not find 112"<<endl;
else cout<<"wo find 112"<<endl;
4,map中元素的删除:
如果删除112;
map<int ,string >::iterator l_it;;
l_it=maplive.find(112);
if(l_it==maplive.end())
cout<<"we do not find 112"<<endl;
else maplive.erase(l_it); //delete 112;
5,map中 swap的用法:
Map中的swap不是一个容器中的元素交换,而是两个容器交换;
For example:
#include <map>
#include <iostream>
using namespace std;
int main( )
{
map <int, int> m1, m2, m3;
map <int, int>::iterator m1_Iter;
m1.insert ( pair <int, int> ( 1, 10 ) );
m1.insert ( pair <int, int> ( 2, 20 ) );
m1.insert ( pair <int, int> ( 3, 30 ) );
m2.insert ( pair <int, int> ( 10, 100 ) );
m2.insert ( pair <int, int> ( 20, 200 ) );
m3.insert ( pair <int, int> ( 30, 300 ) );
cout << "The original map m1 is:";
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << " " << m1_Iter->second;
cout << "." << endl;
// This is the member function version of swap
//m2 is said to be the argument map; m1 the target map
m1.swap( m2 );
cout << "After swapping with m2, map m1 is:";
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << " " << m1_Iter -> second;
cout << "." << endl;
cout << "After swapping with m2, map m2 is:";
for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ )
cout << " " << m1_Iter -> second;
cout << "." << endl;
// This is the specialized template version of swap
swap( m1, m3 );
cout << "After swapping with m3, map m1 is:";
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << " " << m1_Iter -> second;
cout << "." << endl;
}
6.map的sort问题:
Map中的元素是自动按key升序排序,所以不能对map用sort函数:
For example:
#include <map>
#include <iostream>
using namespace std;
int main( )
{
map <int, int> m1;
map <int, int>::iterator m1_Iter;
m1.insert ( pair <int, int> ( 1, 20 ) );
m1.insert ( pair <int, int> ( 4, 40 ) );
m1.insert ( pair <int, int> ( 3, 60 ) );
m1.insert ( pair <int, int> ( 2, 50 ) );
m1.insert ( pair <int, int> ( 6, 40 ) );
m1.insert ( pair <int, int> ( 7, 30 ) );
cout << "The original map m1 is:"<<endl;
for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
cout << m1_Iter->first<<" "<<m1_Iter->second<<endl;
}
The original map m1 is:
1 20
2 50
3 60
4 40
6 40
7 30
请按任意键继续. . .
7, map的基本操作函数:
C++ Maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
NYOJ众数问题:题目95 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=95
众数问题
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数,
多重集合S重的重数最大的元素成为众数。例如:S={1,2,2,2,3,5},则多重集S的众数是2,其重数为3。
现在你的任务是:对于给定的由m个自然数组成的多重集S,计算出S的众数及其重数。
输入
第一行为n,表示测试数据组数。(n<30)
每组测试的第一行是一个整数m,表示多重集S中元素的个数为m
接下来的一行中给出m(m<100)个不大于10万的自然数
(不会出现不同元素出现的次数相同的情况,如:S={11,11,22,22,33,33})。
输出
每组测试数据输出一行,包含两个数,第一个是众数,第二个是其重数,中间以空格隔开。
样例输入
1
6
1 2 2 2 3 5
样例输出
2 3
来源
[rooot]原创
上传者
rooot
AC代码:
#include <iostream>
#include <stack>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
int aa[110];
bool fun(const pair<int,int>&p1,const pair<int,int> &p2)//这里暂时还不太理解.只知道是来比大小,就像排序时候的辅助函数一样。
{
return p1.second<p2.second;
}
int main()
{
int T;
cin>>T;
while(T--)
{
map<int,int>mm;
int n;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>aa[i];
mm[aa[i]]++;
}
map<int,int> ::iterator it;//设置迭代器
it=max_element(mm.begin(),mm.end(),fun);
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
NYOJ:题目991 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=991
Registration system
时间限制:1000 ms | 内存限制:65535 KB
难度:2
描述
A new e-mail service "Berlandesk" is going to be opened in Berland in the near future.
The site administration wants to launch their project as soon as possible, that's why they
ask you to help. You're suggested to implement the prototype of site registration system.
The system should work on the following principle.
Each time a new user wants to register, he sends to the system a request with his name.
If such a name does not exist in the system database, it is inserted into the database, and
the user gets the response OK, confirming the successful registration. If the name already
exists in the system database, the system makes up a new user name, sends it to the user
as a prompt and also inserts the prompt into the database. The new name is formed by the
following rule. Numbers, starting with 1, are appended one after another to name (name1,
name2, ...), among these numbers the least i is found so that namei does not yet exist in
the database.
输入
The first line contains number n (1 ≤ n ≤ 105). The following n lines contain the requests to the system. Each request is a non-empty line, and consists of not more than 1000 characters, which are all lowercase Latin letters.
输出
Print n lines, which are system responses to the requests: OK in case of successful registration, or a prompt with a new name, if the requested name is already taken.
样例输入
4
abacaba
acaba
abacaba
acab
样例输出
OK
OK
abacaba1
OK
来源
爱生活
上传者
TCM_张鹏
AC代码:
#include <iostream>
#include <map>
#include <algorithm>
#include<string>
using namespace std;
char ss[1010];
int main()
{
int T;
cin>>T;
map<string,int>mm;
while(T--)
{
cin>>ss;
if(mm[ss]) cout<<ss<<mm[ss]<<endl;
else cout<<"OK\n";
mm[ss]++;
}
return 0;
}
NYOJ求次数:
题目1112 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=1112
求次数
时间限制:1000 ms | 内存限制:65535 KB
难度:2
描述
题意很简单,给一个数n 以及一个字符串str,区间【i,i+n-1】 为一个新的字符串,i 属于【0,strlen(str)】如果新的字符串出现过ans++,例如:acmacm n=3,那么 子串为acm cma mac acm ,只有acm出现过
求ans;
输入
LINE 1: T组数据(T<10)
LINE 2: n ,n <= 10,且小于strlen(str);
LINE 3:str
str 仅包含英文小写字母 ,切长度小于10w
输出
求 ans
样例输入
2
2
aaaaaaa
3
acmacm
样例输出
5
1
上传者
ACM_王亚龙
AC代码:#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
char ss[100010];
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
cin>>ss;
int i,j,len;
len=strlen(ss);
map<string,int>mm;
for(i=0; i<=len-n; i++)
{
string str;
for(j=i; j<i+n; j++)
str+=ss[j];
mm[str]++;
}
map<string,int>::iterator it;
int ans=0;
for(it=mm.begin(); it!=mm.end(); it++)
{
int mycount=it->second;
if(mycount>=2) ans+=mycount-1;
}
cout<<ans<<endl;
}
return 0;
}
STL之replace:
http://blog.csdn.net/zwj1452267376/article/details/46821527
replace算法:
replace函数包含于头文件#include中。
泛型算法replace把队列中与给定值相等的所有值替换为另一个值,整个队列都被扫描,即此算法的各个版本都在
线性时间内执行———其复杂度为O(n)。
即replace的执行要遍历由区间[frist,last)限定的整个队列,以把old_value替换成new_value。
下面介绍replace()函数常用的九种方法:
用法一:
用str替换指定字符串从起始位置pos开始长度为len的字符
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
line=line.replace(line.find("&"),1,"1");//将line中的第一个&替换成1
cout<<line<<endl;
return 0;
}
用法二:
用str替换 迭代器起始位置 到 结束位置 的字符
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
line=line.replace(line.begin(),line.begin()+6,"1");//将line从begin位置开始的6个字符替换成1
cout<<line<<endl;
return 0;
}
用法三:
用substr的指定子串(给定起始位置和长度)替换从指定位置上的字符串
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
string substr="012345";
line=line.replace(0,5,substr,substr.find("1"),3);//将line字符串0到5位置上的字符替换为substr的指定子串(从'1'位置开始的3个字符)
cout<<line<<endl;
return 0;
}
用法四:
用str替换大串指定位置上的子串(string转char*时编译器可能会报出警告,不建议这样做 )
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
char* str="012345";
line=line.replace(0,5,str);//用str替换从指定位置0开始长度为5的字符串
cout<<line<<endl;
return 0;
}
用法五:
用str替换从指定迭代器位置的字符串 (string转char*时编译器可能会报出警告,不建议这样做 )
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
char* str="012345";
line=line.replace(line.begin(),line.begin()+9,str);
cout<<line<<endl;
return 0;
}
用法六:
用s的前n个字符替换从开始位置pos长度为len的字符串 (string转char*时编译器可能会报出警告,不建议这样做 )
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
char* str="012345";
line=line.replace(0,9,str,5);//用str的前5个字符替换从0位置开始长度为9的字符串
cout<<line<<endl;
return 0;
}
用法七:
用s的前n个字符替换指定迭代器位置(从i1到i2)的字符串 (string转char*时编译器可能会报出警告,不建议这样做 )
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
char* str="012345";
line=line.replace(line.begin(),line.begin()+9,str,5);//用str的前5个字符替换指定迭代器位置的字符串
cout<<line<<endl;
return 0;
}
用法八:
用重复n次的c字符替换从指定位置pos长度为len的内容
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
char c='1';
line=line.replace(0,9,3,c);//用重复3次的c字符替换从指定位置0长度为9的内容
cout<<line<<endl;
return 0;
}
用法九:
用重复n次的c字符替换从指定迭代器位置(从i1开始到结束)的内容
示例代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string line="qwer& &qwer&& &&";
char c='1';
line=line.replace(line.begin(),line.begin()+9,3,c);//用重复3次的c字符替换从指定迭代器中的内容
cout<<line<<endl;
return 0;
}
注:
有使用迭代器类型的参数不限于string类型,可以为vector、list等其他类型迭代器。
STL之find
http://blog.csdn.net/scarletty/article/details/7058398
http://blog.csdn.net/fjn_lhxy/article/details/6626821
NYOJ字符串替换:
http://acm.nyist.net/JudgeOnline/problem.php?pid=113
字符串替换
时间限制:3000 ms | 内存限制:65535 KB
难度:2
描述
编写一个程序实现将字符串中的所有"you"替换成"we"
输入
输入包含多行数据
每行数据是一个字符串,长度不超过1000
数据以EOF结束
输出
对于输入的每一行,输出替换后的字符串
样例输入
you are what you do
样例输出
we are what we do
来源
水题比赛
上传者
hzyqazasdf
AC代码:#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
#include <string>
using namespace std;
//学习replace
int main()
{
string s,s1="you",s2="we";
int flag;
while(getline(cin,s))
{
flag=s.find(s1);
while(flag!=string::npos)//npos 是一个常数,用来表示不存在的位置,
//类型一般是std::container_type::size_type 许多容器都提供这个东西。
{
s.replace(flag,3,s2);
flag=s.find(s1,flag+1);
}
cout<<s<<endl;
}
return 0;
}
STL之next_permutation和prev_permutation:
http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html
这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件
下面是以前的笔记 与之完全相反的函数还有prev_permutation
(1) int 类型的next_permutation
int main()
{
int a[3];
a[0]=1;a[1]=2;a[2]=3;
do
{
cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
} while (next_permutation(a,a+3)); //参数3指的是要进行排列的长度
//如果存在a之后的排列,就返回true。如果a是最后一个排列没有后继,返回false,每执行一次,a就变成它的后继
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果改成 while(next_permutation(a,a+2));
则输出:
1 2 3
2 1 3
只对前两个元素进行字典排序
显然,如果改成 while(next_permutation(a,a+1)); 则只输出:1 2 3
若排列本来就是最大的了没有后继,则next_permutation执行后,会对排列进行字典升序排序,相当于循环
int list[3]={3,2,1};
next_permutation(list,list+3);
cout<
(2) char 类型的next_permutation
int main()
{
char ch[205];
cin >> ch;
sort(ch, ch + strlen(ch) );
//该语句对输入的数组进行字典升序排序。如输入9874563102 cout<<ch; 将输出0123456789,这样就能输出全排列了
char *first = ch;
char *last = ch + strlen(ch);
do {
cout<< ch << endl;
}while(next_permutation(first, last));
return 0;
}
//这样就不必事先知道ch的大小了,是把整个ch字符串全都进行排序
//若采用 while(next_permutation(ch,ch+5)); 如果只输入1562,就会产生错误,因为ch中第五个元素指向未知
//若要整个字符串进行排序,参数5指的是数组的长度,不含结束符
(3) string 类型的next_permutation
int main()
{
string line;
while(cin>>line&&line!="#")
{
if(next_permutation(line.begin(),line.end())) //从当前输入位置开始
cout<<line<<endl;
else cout<<"Nosuccesor\n";
}
}
int main()
{
string line;
while(cin>>line&&line!="#")
{
sort(line.begin(),line.end());//全排列
cout<<line<<endl;
while(next_permutation(line.begin(),line.end()))
cout<<line<<endl;
}
}
next_permutation 自定义比较函数
#include<iostream> //poj 1256 Anagram
#include<string>
#include<algorithm>
using namespace std;
int cmp(char a,char b) //'A'<'a'<'B'<'b'<...<'Z'<'z'.
{
if(tolower(a)!=tolower(b))
return tolower(a)<tolower(b);
else
return a<b;
}
int main()
{
char ch[20];
int n;
cin>>n;
while(n--)
{
scanf("%s",ch);
sort(ch,ch+strlen(ch),cmp);
do
{
printf("%s\n",ch);
}while(next_permutation(ch,ch+strlen(ch),cmp));
}
return 0;
}
NYOJ D的小L:题目366 - ACM在线评测系统
http://acm.nyist.net/JudgeOnline/problem.php?pid=366
D的小L
时间限制:4000 ms | 内存限制:65535 KB
难度:2
描述
一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给匡匡出了个题目想难倒匡匡(小L很D吧 ),有一个数n(0<n<10),写出1到n的全排列,这时匡匡有点囧了 ,,,聪明的你能帮匡匡解围吗?
输入
第一行输入一个数N(0<N<10),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个整数x(0<x<10)
输出
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从小到大排列,组合之间按字典序排列。
样例输入
2
2
3
样例输出
12
21
123
132
213
231
312
321
来源
原创
上传者
kapop
AC代码:#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
int aa[]= {0,1,2,3,4,5,6,7,8,9};
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
int i;
do
{
for(i=1; i<=n; i++)
{
cout<<aa[i];
if(i==n) cout<<"\n";
else cout<<" ";
}
}
while(next_permutation(aa+1,aa+n+1));
}
return 0;
}
STL之%*的使用:
http://blog.csdn.net/zwj1452267376/article/details/46766327
“*”符:用以表示该输入项,读入后不赋予相应的变量,即跳过该输入值。
神一般好用的符号。
AC代码:
#include<stdio.h>
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("\n%*c%d",&n);//\n用来吸收输入t后的回车
//%*c作用时读取输入流中数字前的一个字符,并丢弃,使得后面的输入函数不能读到那个字符
printf("%d\n",n);
}
return 0;
}
STL之二分查找:
http://blog.csdn.net/zwj1452267376/article/details/47150521
二分查找(二分检索):
二分法检索又称折半检索,二分法检索的基本思想是设字典中的元素从小到大有序地存放在数组(array)中, 首先将给定值key与
字典中间位置上元素的关键码(key)比较,如果相等,则检索成功; 否则,若key小,则在字典前半部分中继续进行二分法检索;若
key大,则在字典后半部分中继续进行二分法检索。 这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或
检索失败。 偶数个取中间2个其中任何一个作为中间元素。 二分法检索是一种效率较高的检索方法,要求字典在顺序表中按关
键码排序。
二分查找函数:binary_search():
头文件: #include<algorithm>
函数模板:binary_search(arr[], size , indx)
参数说明: arr[]: 数组首地址;
size: 数组元素个数;
indx: 需要查找的值。
函数功能: 在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则返回其下标,若查找不到则返回值为假。
lower_bound():
头文件: #include<algorithm>
函数模板: 如 binary_search()
函数功能: 函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置
举例如下:
一个数组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的位置是越界的!!~
返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置
upper_bound():
头文件:#include<algorithm>
函数模板: 如binary_search()
函数功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置
例如:一个数组number序列1,2,2,4.upper_bound(2)后,返回的位置是3(下标)也就是4所在的位置,同样,如果插入元素大于数组中全部元素,返回的是last。(注意:数组下标越界)
返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置
注意:
lower_bound(val): 返回容器中第一个值【大于或等于】val的元素的iterator位置。
upper_bound(val): 返回容器中第一个值【大于】val的元素的iterator位置。
拓展:
insert()用法:
比如vector _rows中已经有了{0,1,3,5}
这时要放入4,则std::lower_bound( _rows.begin(), _rows.end(), 4);将会返回5,就是应该插入的那个位置后面的那个值
然后_rows.insert( iter, 4);这句将按照从小到大的顺序将4放进去,最后的顺序是{0,1,3,4,5}