(1)排序与检索
sort函数:对给定区间所有元素进行排序
sort(*start,*end,比较规则);
Sort函数有三个参数:
第一个是要排序的数组的起始地址。
第二个是结束的地址(最后一位要排序的地址的下一地址)
第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
sort可以对任意对象排序,且不一定是内置类型。如果希望用sort排序,该类型需要定义小于运算符或者在排序时第三个参数传入一个“小于”函数,排序对象可以存在于普通数组里,也可以存在于vector中。
对普通数组排序:sort(a,a+n);
对vector数组排序:sort(v.begin(),v.end());
#include#includeusing namespace std; int main() { int a[10]={9,6,3,8,5,2,7,4,1,0}; for(int i=0;i<10;i++) cout< sort(a,a+10);//第三个参数不用写(如果是从小到大排序的话) for(int i=0;i<10;i++) cout< return 0; }
对于从大到小,需要定义compare函数。
#include#includeusing namespace std;bool compare(int a,int b) { return a>b; } int main() { int a[10]={9,6,3,8,5,2,7,4,1,0}; for(int i=0;i<10;i++) cout< //从大到小排序 sort(a,a+10,compare);//在这里就不需要对compare函数传入参数了, //这是规则 for(int i=0;i<10;i++) cout< return 0; }
sort可以对任意对象进行排序,因为sort是一个模板函数。
检索:lower_bound / upper_bound函数
lower_bound(起始地址,结束地址,要查找的数值)
upper_bound(起始地址,结束地址,要查找的数值)
lower_bound(起始地址,结束地址,要查找的数值) 返回的是数值 第一个 出现的位置。
upper_bound(起始地址,结束地址,要查找的数值) 返回的是数值 最后一个 出现的位置。
返回值为地址
例题:大理石在哪儿?
现有N个大理石,每个大理石上写了一个非负整数。首先把各数从小到大排序,然后回答Q个问题。每个问题问是否有一个大理石写着某个整数x,如果是,还要回答哪个大理石上写着x。排序后的大理石从左到右编号为1~N。(在样例中,为了节约篇幅,所有大理石上的数合并到一行,所有问题也合并到一行)
输入三行,第一行两个整数,分别为大理石数目和问题数。
第二行为大理石上的非负整数,用空格隔开。
第三行为问题,用空格隔开。
输出格式见样例。
样例输入:
4 1
2 3 5 1
5
5 2
1 3 3 3 1
2 3
样例输出:
CASE# 1:
5 found at 4
CASE# 2:
2 not found
3 found at 3
分析:排序使用sort,排序后用lower_bound寻找石头及石头位置。
代码:
#include #include using namespace std;int main(){ int N,n,cont=1; while(cin>>N>>n) { int stone[N]; int *p; p=stone; while(p!=stone+N) cin>>*p++; cout< sort(stone,stone+N);//左闭右开,右边无需-1 int re,aim; while(n--) { cin>>aim; p=lower_bound(stone,stone+N-1,aim); re=p-stone; if(stone[re]==aim)cout< else cout< } } return 0;}
得到的测试结果:
(2)不定长数组vector
vector是一个不定长数组。不仅如此,vector将一些常用操作也封装在vector类型内部。
例如,a是一个vector,可以用
a.begin()返回首元素地址
a.end()返回末元素地址
a.size()读取它的大小,返回元素个数
a.resize()改变大小
a.push_back()向尾部添加元素
a.pop_back()删除最后一个元素
a.insert(*p,x)在位置p处插入x;as a.insert(a.begin()+2,-1)
a.erase()有两种用法,删除某区间所有元素或删除单个元素
1.删除单个元素
erase(it)即删除迭代器为it处的元素
2.删除一个区间内的所有元素
erase(first, last)即删除[first, last)内的所有元素,左闭右开
由于vector是一个模板类,定义时需要明确类型。
vectora//定义一个int类型不定长数组,类似于int a[];
vectorb//定义一个double类型不定长数组
vector c//定义一个类似于string c[]的字符串数组
同样地,vector 类型也可以定义二维数组。
vector pile[100]//它的第一维的大小是固定的但第二维大小不固定
例题:木块问题
从左到右有n个木块,编号为0~n-1,要求模拟以下四种操作(下面的a,b都是木块编号)。
① move a onto b 把a和b上方的木块全部归位,然后把a摞在b上面
② move a over b 把a上方木块全部归位,然后把a放在b所在木块堆的顶部
③ pile a onto b 把b上方木块归位,然后把a及a上面的木块整体摞在b上面
④ pile a over b 把a及上面的木块摞在b所在木块堆的顶部
遇到quit时一组数据终止。a和b在同一堆的指令是非法指令,应当忽略。
所有操作结束后输出每个位置的木块列表,按照从底部到顶部的顺序排列。
分析:由vector的性质很容易模拟堆栈问题。由于存在多个堆栈,适合使用二维vector数组
木块问题将在明天解答