Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2563545
  • 博文数量: 315
  • 博客积分: 3901
  • 博客等级: 少校
  • 技术积分: 3640
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-08 15:32
个人简介

知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516

文章分类

全部博文(315)

文章存档

2019年(2)

2018年(1)

2016年(7)

2015年(32)

2014年(39)

2013年(109)

2012年(81)

2011年(44)

分类: C/C++

2012-07-27 13:27:00

点击(此处)折叠或打开

  1. 本篇适合不熟悉这两个函数的读者
  2.     以前在使用stl的过程中发现bind1st和bind2nd这两个函数,当时不太理解什么意思,今天在网上查了一下相关资料发现竟然很简单,下面我就具体解释一下他们的用法。
  3.     bind1st和bind2nd函数用于将一个二元算子(binary functor,bf)转换成一元算子(unary functor,uf)。为了达到这个目的,它们需要两个参数:要转换的bf和一个值(v)。
  4.     可能这么解释以后大家还不是很清楚,那么就说点白话吧。我们在做比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数表示你程序里面的表达式要和k值去比较。上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。大家可能会注意到这里面没有=的比较,先别着急,后面将会说道如何实现=的比较。先举两个例子看看 bind1st和bind2nd的用法。
  5. int a[] = {1, 2, 100, 200};
  6. std::vector< int> arr(a, a + 4);
  7. // 移除所有小于100的元素
  8. arr.erase( std::remove_if( arr.begin(), arr.end(),
  9.     std::bind2nd( std::less< int>(), 100)), arr.end());
  10. 这里的比较表达式相当于arr.value < 100
  11. 如果用bind1st则表达的意思就恰恰相反
  12. // 移除所有大于100的元素
  13. arr.erase( std::remove_if( arr.begin(), arr.end(),
  14.     std::bind1st( std::less< int>(), 100)), arr.end());
  15. 这里的表达式相当于100 < arr.value
  16. 当然为了实现删除大于100的元素你同样可以使用bind2nd
  17. // 移除所有大于100的元素
  18. arr.erase( std::remove_if( arr.begin(), arr.end(),
  19.     std::bind2nd( std::greater< int>(), 100)), arr.end());
  20. (关于greater,我在官网上找了下:
  21. // To sort in descending order, // specify binary predicate greater( ) sort( v1.begin( ), v1.end( ), greater( ) ); cout << "Resorted vector v1 = ( " ; for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ ) cout << *Iter1 << " ";    cout << ")" << endl;
  22. )
  23. 前面说道=的比较,比如说x <= k怎么实现呢,std又提供了一个好东西not1,我们可以说 !(x > k) 和 x <= k是等价的,那么我们看看下面的表达式:
  24. // 移除所有小于等于100的元素
  25. arr.erase( std::remove_if( arr.begin(), arr.end(),
  26.     std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());
  27. 说明:not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数
  28. 例子需要包含头文件
  29. #include <vector>
  30. #include <algorithm>
  31. #include <functional>
关于bind1st、bind2nd的MSDN: 

点击(此处)折叠或打开

  1. // functional_bind2nd.cpp
  2. // compile with: /EHsc
  3. #include <vector>
  4. #include <functional>
  5. #include <algorithm>
  6. #include <iostream>

  7. using namespace std;

  8. // Creation of a user-defined function object
  9. // that inherits from the unary_function base class
  10. class greaterthan15: unary_function<int, bool>
  11. {
  12. public:
  13.     result_type operator()(argument_type i)
  14.     {
  15.         return (result_type)(i > 15);
  16.     }
  17. };

  18. int main()
  19. {
  20.     vector<int> v1;
  21.     vector<int>::iterator Iter;

  22.     int i;
  23.     for (i = 0; i <= 5; i++)
  24.     {
  25.         v1.push_back(5 * i);
  26.     }

  27.     cout << "The vector v1 = ( ";
  28.     for (Iter = v1.begin(); Iter != v1.end(); Iter++)
  29.         cout << *Iter << " ";
  30.     cout << ")" << endl;

  31.     // Count the number of integers > 10 in the vector
  32.     vector<int>::iterator::difference_type result1a;
  33.     result1a = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 10));
  34.     cout << "The number of elements in v1 greater than 10 is: "
  35.          << result1a << "." << endl;

  36.     // Compare counting the number of integers > 15 in the vector
  37.     // with a user-defined function object
  38.     vector<int>::iterator::difference_type result1b;
  39.     result1b = count_if(v1.begin(), v1.end(), greaterthan15());
  40.     cout << "The number of elements in v1 greater than 15 is: "
  41.          << result1b << "." << endl;

  42.     // Count the number of integers < 10 in the vector
  43.     vector<int>::iterator::difference_type result2; //difference_type用于说明两个iterator之间特定条件元素的个数,还有很多类型可以使用,太多啦... 
  44.     result2 = count_if(v1.begin(), v1.end(), bind1st(greater<int>(), 10));
  45.     cout << "The number of elements in v1 less than 10 is: "
  46.          << result2 << "." << endl;
  47. }
  48. The vector v1 = ( 0 5 10 15 20 25 )
  49. The number of elements in v1 greater than 10 is: 3.
  50. The number of elements in v1 greater than 15 is: 2.
  51. The number of elements in v1 less than 10 is: 2.
  52. Requirements
  53. Header: <functional>

  54. Namespace: std
关于iterator、reverse_iterator的MSDN:

点击(此处)折叠或打开

  1. // reverse_iterator_ret_ref.cpp
  2. // compile with: /EHsc
  3. #include <iterator>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <iostream>

  7. int main( )
  8. {
  9.    using namespace std;
  10.    int i;

  11.    vector<int> vec;
  12.    for (i = 1 ; i < 6 ; ++i )
  13.    {
  14.       vec.push_back ( 2 * i );
  15.    }
  16.    
  17.    vector <int>::iterator vIter; //普通迭代器
  18.    cout << "The vector vec is: ( ";
  19.    for ( vIter = vec.begin ( ) ; vIter != vec.end ( ); vIter++ )
  20.       cout << *vIter << " ";
  21.    cout << ")." << endl;

  22.    vector <int>::reverse_iterator rvIter; //反向迭代器
  23.    cout << "The vector vec reversed is: ( ";
  24.    for ( rvIter = vec.rbegin( ) ; rvIter != vec.rend( ); rvIter++)
  25.       cout << *rvIter << " ";
  26.    cout << ")." << endl;

  27.    vector <int>::iterator pos;
  28.    pos = find ( vec.begin ( ), vec.end ( ), 8 ); // 返回值(成功返回第一次出现该值的地址,否则返回string::npos(-1), one past the final element ?):An input iterator addressing the first occurrence of the specified value in the range being searched. If no such value exists in the range, the iterator returned addresses the last position of the range, one past the final element.
  29.    reverse_iterator<vector<int>::iterator> rpos ( pos );

  30.    // Declare a difference type for a parameter
  31.    reverse_iterator<vector<int>::iterator>::difference_type diff = 2;//解释:

    点击(此处)折叠或打开

    1. reverse_iterator<T>(const Iterator &other)
    2. Constructs a reverse_iterator pointing to the element before another iterator
    3. reverse_iterator<vector<int>::iterator> > myItr(myVector.end()); // Get iterator to last elem in myVector
    4. Constructs a new reverse_iterator that points to the element directly before the specified iterator.
  32.    cout << "The iterator pos points to: " << *pos << "." << endl;
  33.    cout << "The iterator rpos points to: " << *rpos << "." << endl;

  34.    // Declare a reference return type & use operator[]
  35.    reverse_iterator<vector<int>::iterator>::reference refrpos = rpos[diff];
  36.    cout << "The iterator rpos now points to: " << refrpos << "." << endl;
  37. }
这里有一个关于find的用法详解:(来自coderdoc网友)

点击(此处)折叠或打开

  1. STL string find使用详解
  2.    2012年6月23日 admin
  3. 由于查找是使用最为频繁的功能之一,string 提供了非常丰富的查找函数。其列表如下:
  4. 函数名 描述 find 查找 rfind 反向查找 find_first_of 查找包含子串中的任何字符,返回第一个位置 find_first_not_of 查找不包含子串中的任何字符,返回第一个位置 find_last_of 查找包含子串中的任何字符,返回最后一个位置 find_last_not_of 查找不包含子串中的任何字符,返回最后一个位置以上函数都是被重载了4次,以下是以find_first_of 函数为例说明他们的参数,其他函数和其参数一样,也就是说总共有24个函数 :

  5. size_type find_first_of(const basic_string& s, size_type pos = 0)
  6.  size_type find_first_of(const charT* s, size_type pos, size_type n)
  7.  size_type find_first_of(const charT* s, size_type pos = 0)
  8.  size_type find_first_of(charT c, size_type pos = 0)

  9. 所有的查找函数都返回一个size_type类型,这个返回值一般都是所找到字符串的位置,如果没有找到,则返回string::npos。有一点需要特别注意,所有和string::npos的比较一定要用string::size_type来使用,不要直接使用int 或者unsigned int等类型。其实string::npos表示的是-1, 看看头文件:

  10. template <class _CharT, class _Traits, class _Alloc>
  11.  const basic_string<_CharT,_Traits,_Alloc>::size_type
  12.  basic_string<_CharT,_Traits,_Alloc>::npos
  13.  = basic_string<_CharT,_Traits,_Alloc>::size_type) -1;

  14. find 和 rfind 都还比较容易理解,一个是正向匹配,一个是逆向匹配,后面的参数pos都是用来指定起始查找位置。对于find_first_of 和find_last_of 就不是那么好理解。

  15. find_first_of 是给定一个要查找的字符集,找到这个字符集中任何一个字符所在字符串中第一个位置。或许看一个例子更容易明白。

  16. 有这样一个需求:过滤一行开头和结尾的所有非英文字符。看看用string 如何实现:
  17. ?
  18.  #include <string>
  19.  #include <iostream>
  20.  using namespace std;
  21.  int main()
  22.  {
  23.  string strinfo=" //*---Hello Word!......------";
  24.  string strset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  25.  int first = strinfo.find_first_of(strset);
  26.  if(first == string::npos)
  27.  {
  28.  cout<<"not find any characters"<<endl;
  29.  return -1;
  30.  }
  31.  int last = strinfo.find_last_of(strset);
  32.  if(last == string::npos)
  33.  {
  34.  cout<<"not find any characters"<<endl;
  35.  return -1;
  36.  }
  37.  cout << strinfo.substr(first, last - first + 1)<<endl;
  38.  return 0;
  39.  }
  40. 这里把所有的英文字母大小写作为了需要查找的字符集,先查找第一个英文字母的位置,然后查找最后一个英文字母的位置,然后用substr 来的到中间的一部分,用于输出结果。下面就是其结果:

  41. Hello Word
  42. 前面的符号和后面的符号都没有了。像这种用法可以用来查找分隔符,从而把一个连续的字符串分割成为几部分,达到 shell 命令中的 awk 的用法。特别是当分隔符有多个的时候,可以一次指定。例如有这样的需求:

  43. ?
  44. 张三|3456123, 湖南
  45.  李四,4564234| 湖北
  46.  王小二, 4433253|北京
  47. 我们需要以 “|” “,”为分隔符,同时又要过滤空格,把每行分成相应的字段。可以作为你的一个作业来试试,要求代码简洁。
  48. 我的实现:
  49. 点击(此处)折叠或打开

    1. string student[3];
    2.     student[0] = "张三|3456123, 湖南";
    3.     student[1] = " 李四,4564234| 湖北";
    4.     student[2] = " 王小二, 4433253|北京";
    5.     //以 “|” “,”为分隔符,同时又要过滤空格; 我认为采用erase进行擦除工作;
    6.     for (int i = 0; i < 3; i++)
    7.     {
    8.         string::size_type _pos = 0;    //更具规范性和关联性
    9.         //int _pos = 0;
    10.         cout << "student is " << student[i] << endl;
    11.         while((_pos = student[i].find(" ", _pos)) != string::npos)
    12.         {
    13.             student[i].erase(_pos, 1);
    14.         }
    15.         cout << "After erase student is " << student[i] << endl;
    16.     }

erase--MSDN:

点击(此处)折叠或打开

  1. // basic_string_erase.cpp
  2. // compile with: /EHsc
  3. #include <string>
  4. #include <iostream>

  5. int main( )
  6. {
  7.    using namespace std;

  8.    // The 1st member function using a range demarcated
  9.    // by iterators
  10.    string str1 ( "Hello world" );
  11.    basic_string <char>::iterator str1_Iter;
  12.    cout << "The original string object str1 is: "
  13.         << str1 << "." << endl;
  14.    str1_Iter = str1.erase ( str1.begin ( ) + 3 , str1.end ( ) - 1 );
  15.    cout << "The first element after those removed is: "
  16.         << *str1_Iter << "." << endl; //me--删除的字符串的后面一个字符;
  17.    cout << "The modified string object str1 is: " << str1
  18.            << "." << endl << endl;

  19.    // The 2nd member function erasing a char pointed to
  20.    // by an iterator
  21.    string str2 ( "Hello World" );
  22.    basic_string <char>::iterator str2_Iter;
  23.    cout << "The original string object str2 is: " << str2
  24.         << "." << endl;
  25.    str2_Iter = str2.erase ( str2.begin ( ) + 5 );
  26.    cout << "The first element after those removed is: "
  27.         << *str2_Iter << "." << endl;
  28.    cout << "The modified string object str2 is: " << str2
  29.         << "." << endl << endl;

  30.    // The 3rd member function erasing a number of chars
  31.    // after a char
  32.    string str3 ( "Hello computer" ), str3m;
  33.    basic_string <char>::iterator str3_Iter;
  34.    cout << "The original string object str3 is: "
  35.         << str3 << "." << endl;
  36.    str3m = str3.erase ( 6 , 8 );
  37.    cout << "The modified string object str3m is: "
  38.         << str3m << "." << endl;
  39. }
结果:
  1. The original string object str1 is: Hello world.
  2. The first element after those removed is: d.
  3. The modified string object str1 is: Held.
  4. The original string object str2 is: Hello World.
  5. The first element after those removed is: W.
  6. The modified string object str2 is: HelloWorld.
  7. The original string object str3 is: Hello computer.
  8. The modified string object str3m is: Hello .

阅读(2058) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~