问题来源
大理石在哪儿 UVa10474
现有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
本题是在刘汝佳《算法竞赛入门经典》5.2的一道题,由于书上是algorithm头文件来实现的,本着年轻就该多尝试的原则,自己换用vector头文件来实现一遍,这为后来挖坑埋下了伏笔
本来是想体验下STL的快然撒腿就跑的,可是,
莫问前路坑多少,该有多少就多少
贴上代码
#include <iostream>
#include <algorithm>
#include <vector>
const int maxn =1000; //c++一般用const来声明定常
using namespace std;
int main()
{
vector<int> a;
int n, T,q , x, y[maxn], kase = 0;
while(cin>> n >> q){
cout<<"The case "<<++kase << endl;
for(int i = 0;i < n; i++){
cin>>y[i];
a.push_back(y[i]);}
sort(a.begin(), a.end());
while(T--){
cin>>x;
vector<int>::iterator p = find(a.begin(), a.end(),x);
if(p != a.end())cout<<x<< "found at"<<*p <<endl; // != string::npos
else cout<< x<< "not found "<<endl;
}
}
return 0;
}
就在此时,在我迷迷糊糊看了看头文件的类模板函数后
template<class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val)
{
while (first!=last)
{
if (*first==val) return first;
++first;
}
return last;
}
我以为自己能够熟练使用了,可是却忘了一个重要的元素——迭代器(iterator)。(《c++primer 5th》p95)书中介绍
迭代器除了vector之外,标准库还定义了其他几种容器。
vector支持下标运算符,这点和string一样;string支持得带起,这也和vector一样。
和指针不一样,获取迭代器不是使用取地址。
不论vector对象本身是否是常量,返回值都是const_iterator
翻译一下就是:迭代器可不和指针一样,他们太too young too simple,要想跟着我我走南闯北,你必须push_back()我的步伐,否则一辈子都不让你追上。但是我还是可以用指针来解引用和成员操作的,你们还是可以获得女神芳心的。无论结局如何,我还是返回const_iterator。
坑,在这里
在编译过程中,一直在苦苦思考
p = find(a.begin(), a.end(),x); //p到底是何方神圣???
先后用int, auto 各种分别去尝试都出现了其中一个错误
error: cannot convert '__gnu_cxx::__normal_iterator<int*, std::vector<int> >' to 'int' in initialization|
内心几乎是崩溃的,那么,又回到了问题的本质:find()函数返回值类型的是什么???从哪里来?到哪里去?
终于,翻开了圣经——c++primer。找到了答案,
不论vector对象本身是否是常量,返回值都是const_iterator
const_iterator是声明iterator指向的对象是常量,即iterator指向常对象,其本身可以变
如果vector对象不是常量,既可以使用iterator也可以使用iterator_const
iterator能读写vector::iterator中的元素
除此之外,我如何取出该容器中的数并且输出呢?
这时需要解引用操作用指针或者箭头运算符取出元素。
这时,答案已经被侦破了。
我要获取输入数组某个元素的位置,find函数返回的是vector::iterator,如果要获取该位置并且输出,则需用指针解引用。