stl非变易算法(二)

这里接着上篇stl非变易算法(一)进行总结。主要解析算法函数count、count_if、mismatch、equal、search、search_n以及find_end,给出算法函数的实现及测试用例。下面直接进入正题。

统计等于某值的容器元素个数count

count函数用于计算容器中某个给定值的出现次数。计算迭代区间[first,last)上等于val值的元素个数ret,返回计数。

//count算法函数的实现代码
template <class InputIterator, class T>
  typename iterator_traits<InputIterator>::difference_type
    count (InputIterator first, InputIterator last, const T& val)
{
  typename iterator_traits<InputIterator>::difference_type  ret = 0;
  while (first!=last)
  {
    if (*first == val)
        ++ret;
    ++first;
  }
  return ret;
}
//测试用例
#include <algorithm>
#include <list>
#include <iostream>
using namespace std;
int main(void)
{
    list<int> l;
    for(int i=0; i<100; i++)
        l.push_back(i%20);
    int num=0;
    int value=9;
    num=count(l.begin(), l.end(), value);
    cout << "链表中元素等于value的元素个数为: "
        << num << endl;
    return 0;
}


条件统计容器元素个数count_if

与count算法函数类似,count_if算法函数只是使用谓词判断pred,统计迭代器区间[first,last)上满足条件的元素个数n,返回计数。

//count_if算法函数代码
template <class InputIterator, class UnaryPredicate>
  typename iterator_traits<InputIterator>::difference_type
    count_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  typename iterator_traits<InputIterator>::difference_type n = 0;
  while (first!=last) {
    if (pred(*first)) ++n;
    ++first;
  }
  return n;
}
//测试用例
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

//是否为奇数
bool IsOdd (int i)
{
    return ((i%2)==1);
}

int main ()
{
    vector<int> v;
    for (int i=1; i<10; i++)
        v.push_back(i);
    int mycount = count_if (v.begin(), v.end(), IsOdd);
    cout << "v容器包含 " << mycount  << " 奇数值。\n";
    return 0;
}


元素不匹配查找mismatch

mismatch算法函数比较两个序列,找出首个不匹配元素的位置。找出迭代区间[first1,last1)上第一个元素i,他与迭代区间[first2,first2+(last1-first1))上的元素(first2+(i-first1))不相等(或不满足二元谓词pred条件)。通过pair返回这两个元素的迭代器,指示不匹配元素 的位置。

)
template <class InputIterator1, class InputIterator2>
  pair<InputIterator1, InputIterator2>
    mismatch (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2);

template <class InputIterator1, class InputIterator2, class BinaryPredicate>
  pair<InputIterator1, InputIterator2>
    mismatch (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, BinaryPredicate pred);
  • mismatch函数的模板类型选择了不同的符号InputIterator1和InputIterator2,表示可取不同的容器迭代器。
//mismatch算法函数的代码
template <class InputIterator1, class InputIterator2>
  pair<InputIterator1, InputIterator2>
    mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
{
  while ( (first1!=last1) && (*first1==*first2) )  // or: pred(*first1,*first2), for version 2
  { ++first1; ++first2; }
  return std::make_pair(first1,first2);
}       
//测试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
bool strEqual(const char* s1, const char* s2){
    return strcmp(s1, s2) == 0 ? 1 : 0;
}

int main(void)
{
    //初始化向量v1、v2
    vector<int> v1, v2;
    v1.push_back(2);
    v1.push_back(0);
    v1.push_back(0);
    v1.push_back(6);

    v2.push_back(2);
    v2.push_back(0);
    v2.push_back(0);
    v2.push_back(7);
    //v1和v2不匹配检查
    pair<vector<int>::iterator, vector<int>::iterator> result1=
        mismatch(v1.begin(), v1.end(), v2.begin());
    if(result1.first == v1.end() && result1.second == v1.end())
        cout << "v1和v2完全相同" << endl;
    else
        cout << "v1和v2不相同,不匹配的数是:\n"
        << *result1.first << endl
        << *result1.second << endl << endl;
    //初始化字符串s1、s2
    char* s1[] = {"apple", "pear", "watermelon", "banana", "grape"};
    char* s2[] = {"apple", "pears", "watermelons", "banana", "grape"};
    //s1和s2不匹配检查
    pair<char**, char**> result2=mismatch(s1, s1+5, s2, strEqual);
    if(result2.first == s1+5 && result2.second ==s2+5)
        cout << "s1和s2完全相同" << endl;
    else
        cout << "s1与s2不相同,不匹配的字符串为:\n"
        << s1[result2.first -s1] << endl
        << s2[result2.second -s2] << endl << endl;
    return 0;
}


元素相等判断equal

类似mismatch、equal算法函数也是逐一比较两个序列的元素是否相等,只是equal函数返回true/false,不返回迭代器值。也是有如下两种使用原型。如果迭代区间[first1,last1)和迭代器区间[first2,first2+(last1-first1))上的元素相等(或满足二元谓词判断条件pred),返回true,否则返回false。

template <class InputIterator1, class InputIterator2>
  bool equal (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2);

template <class InputIterator1, class InputIterator2, class BinaryPredicate>
  bool equal (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, BinaryPredicate pred);
//equal算法函数的代码
template <class InputIterator1, class InputIterator2>
  bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
{
  while (first1!=last1) {
    if (!(*first1 == *first2))   // or: if (!pred(*first1,*first2)), for version 2
      return false;
    ++first1; ++first2;
  }
  return true;
}
//测试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

bool absEqual(int a, int b){
    return (a== abs(b) || abs(a) == b) ? 1:0;
}

int main(void)
{
    //初始化向量v1、v2
    vector <int> v1(5);
    vector <int> v2(5);
    for(unsigned int i = 0; i < v1.size(); i++) {
        v1[i] = i;
        v2[i] = -1 * i;
    }
    //v1、v2相等检查
    if(equal(v1.begin(), v1.end(), v2.begin(), absEqual))
        cout << "v1和v2元素的绝对值完全相等" << endl;
    else
        cout << "v1和v2元素的绝对值不完全相等" << endl;
    return 0;
}


子序列搜索search

search算法函数在一个序列中搜索与另一个序列匹配的子序列。有如下两个原型。在迭代器区间[first1,last1)上找出与迭代器区间[first2,last2)完全匹配(或满足二元谓词判断pred)的子序列,返回子序列首个元素的迭代器值,或返回last1表示没有匹配的子序列。

template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2,
                            BinaryPredicate pred);
//search算法函数的代码
template<class ForwardIterator1, class ForwardIterator2>
  ForwardIterator1 search ( ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2)
{
  if (first2==last2) return first1;  

  while (first1!=last1)
  {
    ForwardIterator1 it1 = first1;
    ForwardIterator2 it2 = first2;
     // or: while (pred(*it1,*it2)) for version 2
    while (*it1==*it2) {
        ++it1; ++it2;
        if (it2==last2) return first1;
        if (it1==last1) return last1;
    }
    ++first1;
  }
  return last1;
}     
//测试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    //初始化向量v1={5, 6, 7, 8, 9 }
    vector<int> v1;
    v1.push_back(5);
    v1.push_back(6);
    v1.push_back(7);
    v1.push_back(8);
    v1.push_back(9);
    //初始化向量v2={7, 8}
    vector<int> v2;
    v2.push_back(7);
    v2.push_back(8);
    //检查v2是否构成v1的子序列
    vector<int>::iterator iterLocation;
    iterLocation=search(v1.begin(), v1.end(), v2.begin(), v2.end());
    //打印从v1[2]开始匹配
    if(iterLocation != v1.end())
        cout << "v2的元素包含在v1中,起始元素为"
        << "v1[" << iterLocation - v1.begin() << "]\n";
    else
        cout << "v2的元素不包含在v1中" << endl;
    return 0;
}


重复元素子序列搜索search_n

search_n算法函数搜索序列中是否有一系列元素值均为某个给定值的子序列。有如下两个原型。分别在迭代器区间[first,last)上搜索是否有count个连续元素,其值均等于value(或满足谓词判断pred的条件),返回子序列首元素的迭代器,或返回last表示没有重复元素的子序列。

template <class ForwardIterator, class Size, class T>
   ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
                             Size count, const T& val);

template <class ForwardIterator, class Size, class T, class BinaryPredicate>
   ForwardIterator search_n ( ForwardIterator first, ForwardIterator last,
                              Size count, const T& val, BinaryPredicate pred );    
//search_n算法函数的代码
template<class ForwardIterator, class Size, class T>
  ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
                            Size count, const T& val)
{
  ForwardIterator it, limit;
  Size i;

  limit=first; std::advance(limit,std::distance(first,last)-count);

  while (first!=limit)
  {
    it = first; i=0;
    while (*it==val)       // or: while (pred(*it,val)) for the pred version
      { ++it; if (++i==count) return first; }
    ++first;
  }
  return last;
} 
//测试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
    vector<int> v;
    v.push_back(1);
    v.push_back(8);
    v.push_back(6);
    v.push_back(6);
    v.push_back(9);
    vector<int>::iterator iLocation;
    iLocation=search_n(v.begin(), v.end(), 2, 6);
    if(iLocation != v.end())
        cout << "在v中找到2个连续的元素6" << endl;
    else
        cout << "v中没有2个连续的元素6" << endl;
    return 0;
}       


最后一个子序列搜索find_end

find_end算法函数在一个序列中搜索出最后一个与另一序列匹配的子序列。有如下两个使用原型。在迭代器区间[first1,last1)中搜索出与迭代器区间[first2,last2)元素匹配的子序列,返回首元素的迭代器或返回last1,表示没有子序列匹配。

template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator2 last2,
                              BinaryPredicate pred);          
//find_end函数实现
template<class ForwardIterator1, class ForwardIterator2>
  ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2)
{
  if (first2==last2) return last1;  // specified in C++11

  ForwardIterator1 ret = last1;

  while (first1!=last1)
  {
    ForwardIterator1 it1 = first1;
    ForwardIterator2 it2 = first2;
    while (*it1==*it2) {    // or: while (pred(*it1,*it2)) for version (2)
        ++it1; ++it2;
        if (it2==last2) { ret=first1; break; }
        if (it1==last1) return ret;
    }
    ++first1;
  }
  return ret;
}
//测试用例
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
    //初始化向量v1={-5, 1, 2, -6, -8, 1, 2, -11}
    vector<int> v1;
    v1.push_back(-5);
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(-6);
    v1.push_back(-8);
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(-11);
    //初始化向量v2={1, 2}
    vector<int> v2;
    v2.push_back(1);
    v2.push_back(2);
    //v1中查找最后一个子序列v2
    vector<int>::iterator iLocation;
    iLocation=find_end(v1.begin(), v1.end(), v2.begin(), v2.end());
    //打印子序列在v1的起始位置v[5]
    if(iLocation != v1.end())
        cout << "v1中找到最后一个匹配v2的子序列,位置在"
        << "v1[" << iLocation - v1.begin() << "]" << endl;
    return 0;
}     



完结。

转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/46849279

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-02 06:35:34

stl非变易算法(二)的相关文章

stl非变易算法(一)

C++ STL的非变易算法是一组不破坏操作数据的模板函数,用来对序列数据进行逐个处理.元素查找.子序列搜索.统计和匹配.非变易算法具有极为广泛的适用性,基本上可应用于各种容器. 逐个容器元素for_each C++ STL提供了一个for_each函数,用于对容器的元素进行循环操作.它对迭代区间[first, last)所指的每一个元素,执行由单参函数对象fn所定义的操作.原型如下: template<class InputIterator, class Function> Function

STL非变易算法

非变易算法:原则上不会变更操作数据的算法. [1]    for_each:逐个容器元素,原型for_each(InputIter first, InputIter last, Function f). [2]    find:顺序查找容器元素,原型InputIter find(InputIter first, InputIter last, constT &val, input_iterator_tag). [3]    find_if:条件查找容器,原型InputIter find_if(I

第21章 非变易算法

   第21章 非变易算法     Non-modifying sequence operations   21.0 advance, distance     为了了解模板,先了解一下这两个迭代器操作函数   21.1 逐个容器元素for_each     for_each  Apply function to range (template function)   21.2 查找容器元素find     find  Find value in range (function template

stl变易算法(一)

C++ STL的变易算法是一组能够修改容器元素数据的模板函数,可进行序列容器的复制.交换.替换.填充.移除.旋转等.这些算法对迭代器有较高的要求,具体的迭代器类型随各个算法而定,或向前迭代器.或双向迭代器.又或者是随机迭代器,以提供算法所需要的迭代器操作.应用变易算法时,先要检查容器的迭代器是否符合要求,防止产生编译错误. 元素复制copy C++STL提供一个用于容器间元素拷贝的copy算法,将迭代区间[first,last)的元素复制到由复制目标迭代器result给定的区间[result,r

stl变易算法(二)

本篇接着前篇stl变易算法(一)继续讲述变易算法.主要介绍transform.replace.replace_if.replace_copy以及replace_copy_if的用法及实现代码,并给出测试用例. 元素变换transform transform算法用于实行容器元素的变换操作.如下两个使用原型,一个将迭代器区间[first,last)中元素,执行一元函数对象op操作,变换后的结果存放在[result,result+(last-first))区间中.另一个将迭代器区间[first1,la

stl变易算法(三)

本篇接着前面stl变易算法(一)和stl变易算法(二)继续讲述变易算法. 这里将介绍完余下的变易算法,主要有:填充fill.n次填充fill_n.随机生成元素generate.随机生成n个元素generate_n.移除复制remove_copy.条件移除复制remove_copy_if.移除remove.条件移除remove_if.不连续反复元素复制unique_copy.剔除连续反复元素unique.元素反向reverse.反向复制reverse_copy及旋转rotate .给出算法实现及实

C++标准模板库-STL库基本算法

原文链接:http://blog.csdn.net/wangfengwf/article/details/11580989#t9 16.4  STL库基本算法 标准C++STL库中算法组件为一个很重要的组成部分,该组件提供了大多数最常见的通用算法的实现,并且这些实现是经过很多测试试验并被公认在处理上是高效的.将这些最常见的算法通用化实现,最大的优势就是开发者在应用中不需要为具体的常见算法的实现而费神,只需要包含相应的头文件直接使用即可,不仅仅提高的软件开发的效率,同时还有助于软件重用性的提高.

第22章 变易算法

  第22章 变易算法  Modifying  sequence operations    22.1 元素复制copycopy  Copy range of elements (function template)      22.2 反向复制copy_backwardcopy_backward  Copy range of elements backwards (function template)      22.3 元素交换swapswap  Exchange values of two

STL中排序算法的选择

 当大多数程序员需要对一组对象进行排序的时候,首先想到的一个算法是sort.sort是一个非常不错的算法,但它也并非在任何场合下都是完美无缺的.有时候我们并不需要一个完全的排序操作.比如说,如果我们有一个存放Widget的矢量,而我们希望将质量最好的20个Widget送给最重要的顾客,按照顾客的重要程度送上不同质量的Widget,那么只需要排序出前20个最好的Widget,其他的Widget可以不用排序.在这种情况下,需要的是一种部分排序的功能,而有一个名为partial_sort的算法正好