find_first_of用法释疑

The C++ Standard Library p353

find_first_of属于非变动性算法,它的两种形式如下:

ForwardIterator1 find_first_of(
      ForwardIterator1 _First1,
      ForwardIterator1 _Last1,
      ForwardIterator2 _First2,
      ForwardIterator2 _Last2
   );
ForwardIterator1 find_first_of(
      ForwardIterator1 _First1,
      ForwardIterator1 _Last1,
      ForwardIterator2 _First2,
      ForwardIterator2 _Last2,
      BinaryPredicate _Comp
   );

先看第一种,书中代码简略如下

ContractedBlock.gif ExpandedBlockStart.gif Code
 1 // 省略部分代码,INSERT_ELEMENTS为插入元素到容器中,PRINT_ELEMENTS为打印容器内所有元素
 2     vector<int> coll;
 3     list<int> searchcoll;
 4     INSERT_ELEMENTS(coll, 111);
 5     INSERT_ELEMENTS(searchcoll, 36);
 6     PRINT_ELEMENTS(coll, "coll: ");
 7     PRINT_ELEMENTS(searchcoll, "searchcoll: ");
 8     vector<int>::iterator pos;
 9     // search first occurrence of an element of searchcoll in coll
10     pos = find_first_of(coll.begin(), coll.end(),    // range
11             searchcoll.begin(),        // beginning of search set
12             searchcoll.end());        // end of search set
13     cout << "first element of searchcoll in coll is element "
14             << distance(coll.begin(), pos) + 1
15             << endl;
16     // search last occurrence of an element of searchcoll in coll
17     vector<int>::reverse_iterator rpos;
18     rpos = find_first_of(coll.rbegin(), coll.rend(),
19             searchcoll.begin(),
20             searchcoll.end());
21     cout << "last element of searchcoll in coll is element "
22             << distance(coll.begin(), rpos.base())
23             << endl;
24 /*
25 *    coll: 1 2 3 4 5 6 7 8 9 10 11
26 *    searchcoll: 3 4 5 6
27 *    first element of searchcoll in coll is element 3
28 *    last element of searchcoll in coll is element 6
29 */

     问题出在第18,这里有点疑问,就是逆向查找以找到searchcoll在coll中的最后一个元素位置,我开始以为既然查找的区间都是使用的逆向迭代器,那么searchcoll也应该使用searchcoll.rbegin(),searchcoll.rend(),更为奇怪的是更改后结果竟然完全相同。后来仔细看了下书才发现(看书不认真,bs下自己~),根据书中所说,find_first_of是返回第一个在源、目标区间出现的元素位置。原来目标区间是一个集合,而这个查找也是集合之间的比较,所以逆正都是无所谓。验证如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
 1     vector<int> coll;
 2     list<int> searchcoll;
 3 //    INSERT_ELEMENTS(coll, 1, 11);
 4 //    INSERT_ELEMENTS(searchcoll, 3, 6);
 5     // insert elements by hand
 6     coll.push_back(11);
 7     coll.push_back(4);
 8     coll.push_back(5);
 9     coll.push_back(2);
10     coll.push_back(7);
11     coll.push_back(8);
12     coll.push_back(10);
13     coll.push_back(9);
14 
15     searchcoll.push_back(12);
16     searchcoll.push_back(8);
17     searchcoll.push_back(7);
18     searchcoll.push_back(4);
19 
20     PRINT_ELEMENTS(coll, "coll: ");
21     PRINT_ELEMENTS(searchcoll, "searchcoll: ");
22     vector<int>::iterator pos;
23     // search first occurrence of an element of searchcoll in coll
24     pos = find_first_of(coll.begin(), coll.end(),    // range
25             searchcoll.begin(),        // beginning of search set
26             searchcoll.end());        // end of search set
27     cout << "first element of searchcoll in coll is element "
28             << distance(coll.begin(), pos) + 1
29             << endl;
30     // search last occurrence of an element of searchcoll in coll
31     vector<int>::reverse_iterator rpos;
32     rpos = find_first_of(coll.rbegin(), coll.rend(),
33                                     searchcoll.begin(),
34                                     searchcoll.end());
35     cout << "last element of searchcoll in coll is element "
36             << distance(coll.begin(), rpos.base())
37             << endl;
38 /*
39 *    coll: 11 4 5 2 7 8 10 9
40 *    searchcoll: 12 8 7 4
41 *    first element of searchcoll in coll is element 2
42 *    last element of searchcoll in coll is element 6
43 */
     我们可以发现,比较的元素即使顺序不一致,只要在目标区间的元素存在于源区间,即会返回相等的第一个数的位置,与目标区间顺序无关。这里注意求distance中,因为是基于0开始的,所以要加一,但在rpos.base()即将逆向迭代器转化为正向迭代器的过程中已做了更改,所以不用加一。

转载于:https://www.cnblogs.com/dyingfire/archive/2009/02/06/eddie.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值