题目:
编写一个函数,接受表示未知类型迭代器的一对值,找出在序列中出现的最频繁的值
主要实现的是一个简单的统计出现次数的功能,不过template 使用过程中遇到一些问题
最初始版本:
template <typename T>
T findMostValue(T tbegin,T tend)
{
std::map< (*T),int > occur_times;
for(T i = tbegin() ; i != tend; ++i)
{
++ occur_times[*i] ;
}
int imax =0;
for(std::map<(*T),int>::iterator i = occur_times.begin() ; i != occur_times.end() ; ++i)
{
if( i->second > imax)
imax = i->second ;
}
std::map<(*T),int>::iterator imost = occur_times.begin()
for(; imost != occur_times.end() ; ++imost)
{
if( imost->second == imax)
break;
}
for(T i = tbegin() ; i != tend; ++i)
{
if (*i == imost->first)
return i;
}
}
利用map 的特性来统计值出现的次数
上面代码的问题是,
std::map< (*T),int > occur_times
*T 这种形式是非法的, 我们需要的是可以通过某一个不确定的迭代器类型T得到其对于的元素类型,才可以定义map
这时候就需要使用
std::iterator_traits
template <typename T>
T findMostValue(T tbegin, T tend)
{
//obtain value type T assign to
std::map<std::iterator_traits<T>::value_type, int > occur_times;
for (T i = tbegin; i != tend; ++i)
{
++occur_times[*i];
}
int imax = 0;
for (std::map<std::iterator_traits<T>::value_type, int>::iterator i = occur_times.begin(); i != occur_times.end(); ++i)
{
if (i->second > imax)
imax = i->second;
}
std::map<std::iterator_traits<T>::value_type, int>::iterator imost = occur_times.begin();
for (; imost != occur_times.end(); ++imost)
{
if (imost->second == imax)
break;
}
for (T i = tbegin; i != tend; ++i)
{
if (*i == imost->first)
return i;
}
}
//test code
int main()
{
std::vector<int> ivec;
for (int i = 0; i <10; ++i)
ivec.push_back(i);
ivec.push_back(3);
std::vector<int>::iterator i = findMostValue(ivec.begin(), ivec.end());
std::cout << *i << std::endl;
return 0;
}
std::iterator_traits
is the type trait class that provides uniform interface to the properties of iterator types. This makes it possible to implement algorithms only in terms of iterators.
The class defines the following types that correspond to the typedefs provided by std::iterator:
difference_type
- a type that can be used to identify distance between iteratorsvalue_type
- the type of the values that can be obtained by dereferencing the iterator. This type isvoid
for output iterators.pointer
- defines a pointer to the type iterated over (value_type
)reference
- defines a reference to the type iterated over (value_type
)iterator_category
- the category of the iterator. Must be one of iterator category tags.
The template can be specialized for user-defined iterators so that the information about the iterator can be retrieved even if the type does not provide the usual typedefs.