STL中要通過迭代器得知下標值,需要用到distance()函數。
distance() 函數用於計算兩個迭代器表示的範圍內包含元素的個數,其語法格式如下:
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type distance (InputIterator first, InputIterator last);
其中,first 和 last 都爲迭代器,其類型可以是輸入迭代器、前向迭代器、雙向迭代器以及隨機訪問迭代器;該函數會返回[first, last)
範圍內包含的元素的個數。
注意,first 和 last 的迭代器類型,直接決定了 distance() 函數底層的實現機制:
- 當 first 和 last 爲隨機訪問迭代器時,distance() 底層直接採用 last - first 求得 [first, last) 範圍內包含元素的個數,其時間複雜度爲
O(1)
常數階;所以對於vector這種可隨機訪問的容器,distance()的兩個參數沒有前後要求。 - 當 first 和 last 爲非隨機訪問迭代器時,distance() 底層通過不斷執行 ++first(或者 first++)直到 first==last,由此來獲取 [first, last) 範圍內包含元素的個數,其時間複雜度爲
O(n)
線性階。所以對於set,map這種非隨機訪問的容器,使用distance()必須要求第一個參數的迭代器位置在第二個的之前,否則程序就會出現錯誤。
另外,distance() 函數定義在<iterator>
頭文件,並位於 std 命名空間中。因此在使用此函數前,程序中應包含頭文件<iterator>。
測試用例1:
#include<bits/stdc++.h>
using namespace std;
struct S
{
int a;
bool operator<(const S &s)const//實現set從大到小排序
{
return a>s.a;
}
};
int main()
{
multiset<S> s;
int n,i,j;
while(cin>>n)
{
S s1;
for(i=0;i<n;++i)
{
int a;
cin>>a;
s1.a=a;
s.insert(s1);
}
multiset<S>::iterator it;
it=s.find(s1);
cout<<distance(s.begin(),it)<<endl;
cout<<distance(it,s.end())<<endl;
for(it=s.begin();it!=s.end();it++)
{
cout<<(*it).a<<" ";
}
}
}
測試用例2:
#include<bits/stdc++.h>
using namespace std;
struct S
{
int a;
bool operator<(const S &s)const//實現set從大到小排序
{
return a>s.a;
}
};
int main()
{
vector<S> s;
int n,i,j;
while(cin>>n)
{
S s1;
for(i=0;i<n;++i)
{
int a;
cin>>a;
s1.a=a;
s.push_back(s1);
}
cout<<distance(s.end(),s.begin())<<endl;
cout<<distance(s.begin(),s.end())<<endl;
}
}