STL_算法_01_查找算法

1、

来自教程:第6讲 PPT.15

 

◆ 常用的查找算法:

1.1、按条件查找N个相邻的元素

( adjacent 是 邻近的意思)

iterator = adjacent_find(iteratorBegin, iteratorEnd); // 默认的相邻关系的判断依据 : 相等(是值相等吗?)

iterator = adjacent_find(iteratorBegin, iteratorEnd, functor判断相邻条件); // 自定义判断相邻关系的函数对象

1.2、二分查找

bool = binary_search(iteratorBegin, iteratorEnd, value);

bool = binary_search(iteratorBegin, iteratorEnd, value, functor二分查找遍历条件);

1.3、等值范围

pair<iterator, iterator> = equal_range(iteratorBegin, iteratorEnd, value);

pair<iterator, iterator> = equal_range(iteratorBegin, iteratorEnd, value, functor遍历条件);

 

1.4、

_Iter::difference_type = count(iteratorBegin, iteratorEnd, value);

1.5、

_Iter::difference_type = count_if(iteratorBegin, iteratorEnd, functor满足条件);

1.6、

iterator = find(iteratorBegin, iteratorEnd, value);

1.7、

iterator = find_if(iteratorBegin, iteratorEnd, functor满足条件);

 

 

1.1、第6讲 PPT.16

◆ adjacent_find():   在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器。否则返回past-the-end。

  ZC: 上面的"past-the-end",应该是指 返回的迭代器 和 vecInt.end() 比较。

ZC: 有两种 参数格式,返回值 都是 iterator。

ZC: 我的 VC6测试代码:

(1)、测试代码 - 1:

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <string>
 6 #include <vector>
 7 #include <set>
 8 
 9 #include <algorithm>    // 算法
10 #include <numeric>    // 算法
11 #include <functional>    // 算法
12 
13 using namespace std;
14 
15 // ZC: 自己编写的 相邻条件判断 的函数对象
16 class TestAdjacent
17 {
18 public:
19     bool operator()(int _i, int _j)
20     {
21         return _i == _j ? true : false;
22 
23         // ZC: 相邻条件判断:_i是_j的一半,只要满足这个条件adjacent_find()就会返回_i所对应的iterator
24         //return return _i == (_j / 2) ? true : false;
25     }
26 };
27 
28 void main()
29 {
30     vector<int> v;
31     v.push_back(1);
32     v.push_back(2);
33     v.push_back(2);
34     v.push_back(3);
35     v.push_back(4);
36     v.push_back(5);
37     v.push_back(5);
38     v.push_back(5);
39     v.push_back(6);
40     v.push_back(7);
41 
42     // ZC: 第1种 参数格式
43     vector<int>::iterator it =  adjacent_find(v.begin(), v.end());
44     printf("%d, 0x%08X\n", *it, *it);
45     if (it == v.end())
46     {
47         printf("it == v.end()\n");
48         printf("0x%08X, 0x%08X\n", it, v.end());
49     }
50 
51     it =  adjacent_find(it, v.end());
52     printf("%d, 0x%08X\n", *it, *it);
53 
54     it ++;
55     it =  adjacent_find(it, v.end());
56     printf("%d, 0x%08X\n", *it, *it);
57 
58 
59     // ***
60     printf("\n");
61 
62     // ZC: 第2种 参数格式
63     it = adjacent_find(v.begin(), v.end(), TestAdjacent());
64     if (it == v.end())
65     {
66         printf("it == v.end()\n");
67         printf("0x%08X, 0x%08X\n", it, v.end());
68     }
69     else
70         printf("%d, 0x%08X\n", *it, *it);
71 }

控制台输出为:

1 2, 0x00000002
2 2, 0x00000002
3 5, 0x00000005
4 
5 2, 0x00000002
6 Press any key to continue

 

(2)、测试代码 - 2:

 1     vector<int> v;
 2     v.push_back(1);
 3     //v.push_back(2);
 4     v.push_back(2);
 5     v.push_back(3);
 6     v.push_back(4);
 7     v.push_back(5);
 8     //v.push_back(5);
 9     //v.push_back(5);
10     v.push_back(6);
11     v.push_back(7);
12 
13     vector<int>::iterator it =  adjacent_find(v.begin(), v.end());
14     printf("%d, 0x%08X\n", *it, *it);
15     if (it == v.end())
16     {
17         printf("it == v.end()\n");
18         printf("0x%08X, 0x%08X\n", it, v.end());
19     }

 

控制台输出:

1 -842150451, 0xCDCDCDCD
2 it == v.end()
3 0x00272D9C, 0x00272D9C
4 Press any key to continue

 

1.2、第6讲 PPT.17

◆ binary_search():   在有序序列中查找value,找到则返回true。注意:在无序序列中,不可使用。

  ZC:两分查找

ZC: 有两种 参数格式,返回值 都是 bool 。

ZC: VC6 测试代码:

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 // ZC: 两分查找所使用的 比较函数对象
15 class CompareIntFunctor
16 {
17 public:
18     bool operator () (const int _iLeft, const int _iRight)
19     {
20         // ZC: 这里是使用"<"还是">",就要看 set<int> 中使用的是何种排序方式了。
21         // ZC: 注意,貌似 使用"<="或者">=" 得不到想要的结果...
22         return _iLeft < _iRight;
23     }
24 };
25 
26 // ZC: 两分查找所使用的 比较函数
27 bool CompareInt (const int _iLeft, const int _iRight)
28 {
29     return _iLeft < _iRight;
30 }
31 
32 void main()
33 {
34     set<int> setInt;
35     setInt.insert(3);
36     setInt.insert(1);
37     setInt.insert(7);
38     setInt.insert(5);
39     setInt.insert(9);
40 
41     bool bFind = binary_search(setInt.begin(), setInt.end(), 7, CompareIntFunctor()); // 参数格式 - 1
42     printf("bFind : %d\n", bFind);
43 
44     bFind = binary_search(setInt.begin(), setInt.end(), 7, CompareInt); // 参数格式 - 1
45     printf("bFind : %d\n", bFind);
46 
47     bFind = binary_search(setInt.begin(), setInt.end(), 7); // 参数格式 - 2
48     printf("bFind : %d\n", bFind);
49 
50     bFind = binary_search(setInt.begin(), setInt.end(), 8); // 参数格式 - 2
51     printf("bFind : %d\n", bFind);
52 }

ZC:控制台输出为:

1 bFind : 1
2 bFind : 1
3 bFind : 1
4 bFind : 0
5 Press any key to continue

 

ZC: VC6中出现警告:"identifier was truncated to '255' characters in the debug information" :

  可以无视。说的是调试信息中的标示符被截断了。 

问题是因为VC6对STL的一些不完全支持造成,手工屏蔽就可以。
方法为在源文件头部加入一下预编译代码
#ifdef WIN32
#pragma warning (disable: 4514 4786)
#endif

 

 

1.3、第6讲 PPT.21
◆ equal_range() :    返回一对iterator,第一个表示lower_bound,第二个表示upper_bound。
ZC:VC6中可以用于无序序列(可能是检查的不严格);在vs2010中 若用于无序序列 编译不报错 Debug版exe运行时会被assert中断 Release版运行时结果和VC6相同。(注意这里说的是"无序序列",不是"无序容器"。"无序容器"中的元素经过排序后,vs2010的Debug版的exe也不会被assert中断。)

ZC: VC6 测试代码 - 1(参数格式 - 1):

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 void main()
15 {
16     // (1)、无序容器 且 未经过排序
17     vector<int> vecInt;
18     vecInt.push_back(1);
19     vecInt.push_back(2);
20     vecInt.push_back(2);
21     vecInt.push_back(4);
22     vecInt.push_back(2);
23     vecInt.push_back(5);
24 
25     pair<vector<int>::iterator, vector<int>::iterator> pairRstVec = equal_range(vecInt.begin(), vecInt.end(), 2);
26     printf("*pairRstVec.first : %d\n", *pairRstVec.first);
27     printf("*pairRstVec.second : %d\n", *pairRstVec.second);
28 
29     vector<int>::iterator itVec = NULL;
30     int iIdx = 0;
31     for (itVec = pairRstVec.first; itVec != pairRstVec.second; itVec++, iIdx++)
32         printf("[%02d] ==> *itVec : %d\n", iIdx, *itVec);
33         //iIdx ++;
34 
35     printf("\n");
36 
37     // (2)、有序容器
38     multiset<int> msetInt;
39     msetInt.insert(3);
40     msetInt.insert(1);
41     msetInt.insert(7);
42     msetInt.insert(3);
43     msetInt.insert(5);
44     msetInt.insert(3);
45     msetInt.insert(9);
46     msetInt.insert(3);
47     msetInt.insert(3);
48 
49     pair<multiset<int>::iterator, multiset<int>::iterator> pairRstSet = equal_range(msetInt.begin(), msetInt.end(), 3);
50     printf("*pairRstSet.first : %d\n", *pairRstSet.first);
51     printf("*pairRstSet.second : %d\n", *pairRstSet.second);
52 
53     multiset<int>::iterator itSet = NULL;
54     iIdx = 0;
55     for (itSet = pairRstSet.first; itSet != pairRstSet.second; itSet++, iIdx++)
56         printf("[%02d] ==> *itSet : %d\n", iIdx, *itSet);
57 }

ZC:控制台输出 - 1:

 1 *pairRstVec.first : 2
 2 *pairRstVec.second : 4
 3 [00] ==> *itVec : 2
 4 [01] ==> *itVec : 2
 5 
 6 *pairRstSet.first : 3
 7 *pairRstSet.second : 5
 8 [00] ==> *itSet : 3
 9 [01] ==> *itSet : 3
10 [02] ==> *itSet : 3
11 [03] ==> *itSet : 3
12 [04] ==> *itSet : 3
13 Press any key to continue

ZC: VC6 测试代码 - 2(参数格式 - 2):

  ZC: 注意,排序和检索时应该使用相同的方式(排序时使用升序,则检索时也应该使用升序,反之亦然)

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 class TStudent
15 {
16 public:
17     TStudent(int _iAge)
18     {
19         FiAge = _iAge;
20         FiID = _iAge + 1000;
21     };
22 
23     int FiID;
24     int FiAge;
25 };
26 
27 bool Compare(const TStudent& left, const TStudent& right)
28 {
29     return left.FiAge < right.FiAge;
30     //return left.FiAge > right.FiAge;
31 }
32 
33 struct StuFunctor
34 {
35 public:
36     bool operator() (const TStudent& stuLeft, const TStudent& stuRight)
37     {
38         return (stuLeft.FiAge < stuRight.FiAge);
39     }
40 };
41 
42 
43 void main()
44 {
45     //set<TStudent, Compare> setStu; // ZC: 这里传 函数指针 是不行的,只能传 函数对象
46     set<TStudent, StuFunctor> setStu;
47     setStu.insert(TStudent(3));
48     setStu.insert(TStudent(1));
49     setStu.insert(TStudent(5));
50     TStudent stu2(2);
51     setStu.insert(stu2);
52 
53     // ZC: 下面,第3个 参数直接传的是一个 int值,居然也是OK的...
54     pair<set<TStudent, StuFunctor>::iterator, set<TStudent, StuFunctor>::iterator> pair1 = equal_range(setStu.begin(), setStu.end(), 1, StuFunctor());
55     set<TStudent, StuFunctor>::iterator it = pair1.first;
56     while (it != pair1.second)
57     {
58         printf("%d == > %d\n", it->FiAge, it->FiID);
59         it ++;
60     }
61 
62     printf("*** *** *** *** ***\n");
63 
64     pair<set<TStudent, StuFunctor>::iterator, set<TStudent, StuFunctor>::iterator> pair2 = equal_range(setStu.begin(), setStu.end(), stu2, Compare);
65     it = pair2.first;
66     while (it != pair2.second)
67     {
68         printf("%d == > %d\n", it->FiAge, it->FiID);
69         it ++;
70     }
71 }

ZC:控制台输出 - 2:

1 1 == > 1001
2 *** *** *** *** ***
3 2 == > 1002
4 Press any key to continue

 

 

1.4、第6讲 PPT.18

◆ count() :     利用等于操作符,把标志范围内的元素与输入值比较,返回相等的个数
ZC: 只有一种 参数格式,返回值 是 _Iter::difference_type 。
ZC:VC6测试代码:
 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 void main()
15 {
16     vector<int> vecInt;
17     vecInt.push_back(1);
18     vecInt.push_back(2);
19     vecInt.push_back(2);
20     vecInt.push_back(4);
21     vecInt.push_back(2);
22     vecInt.push_back(5);
23 
24     int iCount = count(vecInt.begin(), vecInt.end(), 2);    //iCount==3
25     printf("iCount : %d\n", iCount);
26 }
ZC: 控制台输出:
1 iCount : 3
2 Press any key to continue

 

1.5、第6讲 PPT.18
◆ count_if() :  利用输入的函数,对标志范围内的元素进行比较操作,返回结果为true的个数
ZC: 只有一种 参数格式,返回值 是 _Iter::difference_type 。

ZC: VC6测试代码:

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 //先定义比较函数
15 bool GreaterThree(int iNum)
16 {
17     if (iNum >= 3)
18     {
19         return true;
20     }
21     else
22     {
23         return false;
24     }
25 }
26 
27 void main()
28 {
29     vector<int> vecInt;
30     vecInt.push_back(1);
31     vecInt.push_back(2);
32     vecInt.push_back(2);
33     vecInt.push_back(4);
34     vecInt.push_back(2);
35     vecInt.push_back(5);
36 
37     int iCount = count_if(vecInt.begin(), vecInt.end(), GreaterThree);// ZC: 注意这里传入的是比较函数的函数地址
38     printf("iCount : %d\n", iCount);
39 }

ZC:控制台输出:

1 iCount : 2
2 Press any key to continue

 

1.6、第6讲 PPT.22

◆ find() :  利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的迭代器。(ZC: 应该是找到后,立即返回)

ZC: VC6 测试代码:

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 void main()
15 {
16     vector<int> vecInt;
17     vecInt.push_back(1);
18     vecInt.push_back(3);
19     vecInt.push_back(5);
20     vecInt.push_back(7);
21     vecInt.push_back(9);
22 
23     vector<int>::iterator it = find(vecInt.begin(), vecInt.end(), 5);    //*it == 5
24     printf("*it : %d\n", *it);
25 }

ZC:控制台输出:

1 *it : 5
2 Press any key to continue

 

 

1.7、第6讲 PPT.23

◆ find_if() :   使用输入的函数代替等于操作符执行find。返回被找到的元素的迭代器。

ZC: VC6 测试代码:

 1 #ifdef WIN32
 2 #pragma warning (disable: 4786)
 3 #endif
 4 
 5 #include <vector>
 6 #include <set>
 7 
 8 #include <algorithm>    // 算法
 9 #include <numeric>    // 算法
10 #include <functional>    // 算法
11 
12 using namespace std;
13 
14 bool GreaterThree(int iNum)
15 {
16     if (iNum >= 3)
17     {
18         return true;
19     }
20     else
21     {
22         return false;
23     }
24 }
25 
26 void main()
27 {
28     vector<int> vecInt;
29     vecInt.push_back(1);
30     vecInt.push_back(3);
31     vecInt.push_back(5);
32     vecInt.push_back(7);
33     vecInt.push_back(9);
34 
35     vector<int>::iterator it = find_if(vecInt.begin(), vecInt.end(), GreaterThree);
36     printf("*it : %d\n", *it);
37     printf("*(it+1) : %d\n", *(it+1));
38     printf("*(it+2) : %d\n", *(it+2));
39     printf("*(it+3) : %d\n", *(it+3));
40 }

ZC:控制台输出:

1 *it : 3
2 *(it+1) : 5
3 *(it+2) : 7
4 *(it+3) : 9
5 Press any key to continue

 

 

 

 

 

 

?.?、第6讲 PPT.?

◆ 

ZC: VC6 测试代码:

ZC:控制台输出:

 

X

 

posted @ 2016-03-03 15:50  CppSkill  阅读(336)  评论(0)    收藏  举报