博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STL学习笔记--非变易算法
阅读量:6610 次
发布时间:2019-06-24

本文共 12815 字,大约阅读时间需要 42 分钟。

非变易算法

  C++ STL 的非变易算法(Non-mutating algorithm)是一组不破坏操作数据的模板函数,用来对序列数据进行逐个处理、元素查找、子序列搜索、统计和匹配。作为算法函数参数的迭代器,一般为 Input Iterator 输入迭代器,具有 "++" 迭代和 "*" 访问操作。通过迭代器的元素遍历,可对迭代器区间所界定的元素进行操作。因此,非变易算法具有极为广泛的适用性,基本上可应用于各种容器。

目录:

 

逐个容器元素 for_each
1 /*    下面的示例程序将 list 链表容器的元素,调用 for_each 算法函数,通过 print 函数对象,将各个链表的元素乘以3后打印,并输出元素个数 2 */ 3 -------------------------------------------------------- 应用 for_each 算法遍历 list 容器 4 #include 
// 这个头文件很重要的哦 5 #include
6 #include
7 using namespace std; 8 9 struct print10 {11 int count; // 打印的元素计数12 print(){count=0;}13 void operator() (int x)14 {15 cout << 3*x << endl;16 count++;17 }18 };19 20 int main()21 {22 // 双向链表初始化23 list
lInt;24 lInt.push_back(29);25 lInt.push_back(32);26 lInt.push_back(16);27 lInt.push_back(22);28 lInt.push_back(28);29 lInt.push_back(27);30 31 // 打印链表的元素32 print p = for_each(lInt.begin(), lInt.end(), print());33 // 打印的元素个数34 cout <<"元素个数为:"<
<< endl;35 36 return 0;37 }

 

 

查找容器元素 find
1 /*    下面示例程序利用 find 算法函数查找 list 链表中第一个值为 14 的元素 2 */ 3 -------------------------------------------------------- 应用 find 算法查找 list 容器的元素 4 #include 
5 #include
6 #include
7 using namespace std; 8 int main() 9 {10 // 双向链表初始化11 list
lInt;12 lInt.push_back(100);13 lInt.push_back(10);14 lInt.push_back(14);15 lInt.push_back(13);16 lInt.push_back(14);17 lInt.push_back(40);18 19 // 查找元素 1420 list
::iterator iLocation = find(lInt.begin(), lInt.end(), 14);21 if (iLocation != lInt.end())22 cout << "找到元素14 " << endl;23 24 // 打印第一个14元素前面的那个元素。即打印元素 1025 cout << "前一个元素为:" << *(--iLocation) << endl;26 27 return 0;28 }

 

 

条件查找容器元素 find_if
1 /*    下面示例程序使用 find_if 算法在 vector 向量容器上查找首个可被5整除的元素,程序输出为“找到第一个能被5整除的元素15,元素的索引位置为2” 2 */ 3 -------------------------------------------------------- 应用 find_if 算法条件查找 vector 容器的元素 4 #include 
5 #include
6 #include
7 using namespace std; 8 9 // 谓词判断函数 divby510 bool divby5(int x)11 {12 return x%5 ? 0 : 1;13 }14 15 int main()16 {17 vector
vInt(20); // 可以参考之前对 vector 的介绍18 for (unsigned int i=0; i
::iterator iLocation;22 iLocation = find_if(vInt.begin(), vInt.end(), divby5);23 24 if (iLocation != vInt.end())25 cout << "找到第一个能被5整除的元素:"26 << *iLocation << endl // 打印1527 << "元素的索引位置为:"28 << iLocation-vInt.begin() << endl; // 打印229 30 return 0;31 }

 

 

邻近查找容器元素 adjacent_find
1 /*    调用 adjacent_find 算法函数找出邻近相等的元素11(链表中,有2个11是临近的),再利用是否为奇偶相同,做谓词判断,找出首先同为奇数的 9和11. 2 */ 3 -------------------------------------------------------- 应用 adjacent_find 算法临近查找容器的元素 4 #include 
5 #include
6 #include
7 using namespace std; 8 9 bool parity_equal (int x, int y)10 {11 return (x-y)%2 == 0 ? 1 :0;12 }13 14 int main()15 {16 // 初始化链表17 list
lInt;18 lInt.push_back(3);19 lInt.push_back(6);20 lInt.push_back(9);21 lInt.push_back(11);22 lInt.push_back(11);23 lInt.push_back(18);24 lInt.push_back(20);25 lInt.push_back(20);26 // 查找邻接相等的元素27 list
::iterator iResult = adjacent_find(lInt.begin(), lInt.end());28 if (iResult != lInt.end())29 {30 cout << "发现链表有两个邻接的元素相等" << endl;31 cout << *iResult << endl; // 打印第1 个1132 ++iResult;33 cout << *iResult << endl; // 打印第2 个1134 }35 36 // 查找奇偶性相同的邻接元素37 iResult = adjacent_find(lInt.begin(), lInt.end(), parity_equal);38 if (iResult != lInt.end())39 {40 cout << "发现有两个邻接元素的奇偶性相同" << endl;41 cout << *iResult << endl; // 打印 942 ++iResult;43 cout << *iResult << endl; // 打印 1144 }45 46 return 0;47 }

 

 

范围查找容器元素 find_first_of
1 /*    下面示例程序在字符串 "abcdef7ghijklmn" 中查找首个出现在字符串 "zyx3pr7ys" 的字符,结果当然是字符 7 2 */ 3 -------------------------------------------------------- 应用 find_first_of 算法范围查找容器元素 4 #include 
5 #include
6 using namespace std; 7 int main() 8 { 9 // 定义2个字符串10 char* str1 = "abcdef7ghijklmn";11 char* str2 = "zyx3pr7ys";12 // 范围查找 str1 于 str2 中13 char* result = find_first_of(str1, str1 + strlen(str1),14 str2, str2 + strlen(str2));15 cout << "字符串 str1 的第一个出现在 str2 的字符为:"16 << *result << endl; // 打印 717 18 return 0;19 }

 

 

统计等于某值的容器元素个数 count
1 /*    下面的示例程序链入100个20的余数到双向链表 list 中,然后统计其中等于 9 的元素个数。 2 */ 3  4 -------------------------------------------------------- 应用 count 算法统计等于某值的容器元素个数 5 #include 
6 #include
7 #include
8 using namespace std; 9 int main()10 {11 // 链表初始化12 list
lInt;13 for (int i=0; i<100; i++)14 lInt.push_back(i%20);15 // 统计链表中等于 value 值的元素个数16 int num = 0;17 int value = 9;18 num = count(lInt.begin(), lInt.end(), value);19 cout << "链表中元素等于 value 的元素个数为:"20 << num << endl; // 打印521 22 return 0;23 }

 

 

条件统计容器元素个数 count_if
1 /*    下面示例程序,将学生记录放入使用红黑树的 map 容器,然后利用一元谓词判断 setRange20_30 ,统计年龄在20至30岁之间的学生人数 2 */ 3  4 -------------------------------------------------------- 应用 count_if 算法统计满足条件的记录数 5 #pragma warning(disable:4786) 6 #include 
7 #include
8 #include
9 using namespace std;10 11 // 学生记录结构体12 struct StudentRecord13 {14 struct StudentInfo15 {16 char* name;17 int year;18 char* addr;19 };20 int id; // 学号21 StudentInfo sf; // 学生信息22 StudentRecord(int id_, char* name_, int year_, char* addr_)23 {24 id = id_;25 sf.name = name_;26 sf.year = year_;27 sf.addr = addr_;28 }29 };30 31 bool setRange20_30(pair
s)32 {33 // 20 < x < 3034 if (s.second.year > 20 && s.second.year < 30)35 return 1;36 37 return 0;38 }39 40 int main()41 {42 // 学生数据43 StudentRecord st1 = StudentRecord(1, "李强", 21, "北京");44 StudentRecord st2 = StudentRecord(2, "李文", 29, "山东");45 StudentRecord st3 = StudentRecord(3, "张三", 12, "江苏");46 StudentRecord st4 = StudentRecord(4, "李四", 23, "武汉");47 StudentRecord st5 = StudentRecord(5, "王五", 32, "上海");48 49 // 映照容器50 map
m;51 // 插入 5条学生记录52 pair
pairSt1(st1.id, st1.sf);53 m.insert(pairSt1);54 pair
pairSt2(st2.id, st2.sf);55 m.insert(pairSt2);56 pair
pairSt3(st3.id, st3.sf);57 m.insert(pairSt3);58 pair
pairSt4(st4.id, st4.sf);59 m.insert(pairSt4);60 pair
pairSt5(st5.id, st5.sf);61 m.insert(pairSt5);62 63 // 条件统计64 int num = 0;65 num = count_if(m.begin(), m.end(), setRange20_30);66 cout << "年龄介于20至30之间的学生人数为:"67 << num << endl; // 打印 368 69 return 0;70 }

 

 

元素不匹配查找 mismatch
1 /*    下面示例程序,分别使用了 mismatch 算法函数的两种形式。 2 */ 3  4 -------------------------------------------------------- 应用 msimatch 算法比较两个序列的元素 5 #include 
6 #include
7 #include
8 using namespace std; 9 10 bool strEqual(const char* s1, const char* s2)11 {12 return strcmp(s1, s2) == 0 ? 1: 0;13 }14 15 int main()16 {17 vector
v1, v2;18 v1.push_back(2);19 v1.push_back(0);20 v1.push_back(0);21 v1.push_back(6);22 23 v2.push_back(2);24 v2.push_back(0);25 v2.push_back(0);26 v2.push_back(7);27 28 // v1 和 v2 不匹配检查29 pair
::iterator, vector
::iterator> result = mismatch(v1.begin(), v1.end(), v2.begin());30 31 if (result.first == v1.end() && result.second == v1.end())32 cout << "v1 和 v2 完全相同" << endl;33 else34 cout << "v1 和 v2 不相同,不匹配的数是:\n"35 << *result.first << endl36 << *result.second << endl << endl;37 38 39 // 初始化字符串 s1、s240 char* s1[]={ "apple", "pear", "watermelon", "banana", "grape"};41 char* s2[]={ "apple", "pears", "watermelons", "banana", "grape"};42 // s1 和 s2 不匹配检查43 pair
result2 = mismatch(s1, s1+5, s2, strEqual);44 if (result2.first == s1+5 && result2.second == s2+5)45 cout << "s1和s2完全相同" << endl;46 else47 cout << "s1 与 s2不相同,不匹配的字符串为:\n"48 << s1[result2.first - s1] << endl49 << s2[result2.second - s2] << endl << endl;50 51 return 0;52 }

 

 

元素相等判断 equal
1 /*    下面示例程序,利用二元谓词判断 absEqual ,判断出两个 vector 向量容器的元素均绝对值相等。 2 */ 3  4 -------------------------------------------------------- 应用 equal 算法判断容器元素是否绝对值相等 5 #include 
6 #include
7 #include
8 using namespace std; 9 10 bool absEqual(int a, int b)11 {12 return (a==abs(b) || abs(a)==b) ? 1 : 0;13 }14 15 int main()16 {17 vector
v1(5);18 vector
v2(5);19 for (unsigned int i=0; i

 

 

子序列搜索 search
1 /*    下面示例程序,搜索 vector 向量 V1={5, 6, 7, 8, 9}是否包含子序列向量容器 v2={7, 8}. 2 */ 3  4 -------------------------------------------------------- 应用 search 方法搜索子序列 5 #include 
6 #include
7 #include
8 using namespace std; 9 int main()10 {11 // 初始化向量 v112 vector
v1;13 v1.push_back(5);14 v1.push_back(6);15 v1.push_back(7);16 v1.push_back(8);17 v1.push_back(9);18 // 初始化向量 v219 vector
v2;20 v2.push_back(7);21 v2.push_back(8);22 // 检查 v2 是否构成 v1 的子序列23 vector
::iterator iterLocation;24 iterLocation = search(v1.begin(), v1.end(), v2.begin(), v2.end());25 // 打印从 v1[2]开始匹配26 if (iterLocation != v1.end())27 cout << "v2 的元素包含在 v1 中,起始元素为:"28 << "v1[" << iterLocation - v1.begin() << "] \n";29 else30 cout << "v2的元素不包含在v1中." << endl;31 32 return 0;33 }

 

 

重复元素子序列搜索 search_n
1 /*    下面示例程序,搜索出向量 v={1, 8, 8, 8, 6, 6, 8}中有3个连续元素8、没有4个连续的元素8,以及有2个连续元素6 2 */ 3  4 -------------------------------------------------------- 应用 search_n 算法搜索重复元素值 5 #include 
6 #include
7 #include
8 using namespace std; 9 int main()10 {11 // 初始化向量 v12 vector
v;13 v.push_back(1);14 v.push_back(8);15 v.push_back(8);16 v.push_back(8);17 v.push_back(6);18 v.push_back(6);19 v.push_back(8);20 21 // 查找子序列 {8, 8, 8}22 vector
::iterator iLocation;23 iLocation = search_n(v.begin(), v.end(), 3, 8);24 if (iLocation != v.end())25 cout << "在v中找到3个连续的元素8" << endl;26 else27 cout << "v中没有3个连续的元素8" << endl;28 29 // 查找子序列 {8, 8, 8, 8}30 iLocation = search_n(v.begin(), v.end(), 4, 8);31 if (iLocation != v.end())32 cout << "在v中找到4个连续的元素8" << endl;33 else34 cout << "v中没有4个连续的元素8" << endl;35 36 // 查找子序列{6, 6}37 iLocation = search_n(v.begin(), v.end(), 2, 6);38 if (iLocation != v.end())39 cout << "在v中找到2个连续的元素6" << endl;40 else41 cout << "v中没有2个连续的元素6" << endl;42 43 return 0;44 }

 

 

最后一个子序列搜索 find_end
1 /*    下面示例程序,搜索向量 v1={-5, 1, 2, -6, -8, 1, 2, -11}中最后一个与V2={1, 2}匹配的子序列,打印输出为 "v1中找到最后一个匹配v2的子序列,位置在 v1[5]" 2 */ 3 -------------------------------------------------------- 应用 find_end 算法搜索最后一个匹配子序列 4 #include 
5 #include
6 #include
7 using namespace std; 8 int main() 9 {10 // 初始化向量 v111 vector
v1;12 v1.push_back(-5);13 v1.push_back(1);14 v1.push_back(2);15 v1.push_back(-6);16 v1.push_back(-8);17 v1.push_back(1);18 v1.push_back(2);19 v1.push_back(-11);20 21 // 初始化向量 v222 vector
v2;23 v2.push_back(1);24 v2.push_back(2);25 26 // v1中查找最后一个子序列 v227 vector
::iterator iLocation;28 iLocation = find_end(v1.begin(), v1.end(), v2.begin(), v2.end());29 30 // 打印子序列在 v1 的起始位置 v[5]31 if (iLocation != v1.end())32 cout << "v1中找到最后一个匹配 v2 的子序列,位置在"33 << "v1[" << iLocation - v1.begin() << "] \n"; 34 35 36 return 0;37 }

 

 

------------ 非变易算法小结

    C++ STL 算法库中的非变易算法,是一些原则上不会变更操作数据的算法,包括可逐元素循环提交处理的 for_each 算法、用于元素查找的 find/find_if/adjacent_find/find_first_of 算法、用于统计元素个数的 count/count_if 算法、两序列匹配比较 mismatch/equal 算法和子序列搜索 search/search_n/find_end 算法。

 

 

转载于:https://www.cnblogs.com/music-liang/archive/2013/04/13/3018783.html

你可能感兴趣的文章
《此生未完成》读后感
查看>>
DIV背景图片定位问题
查看>>
Knockout应用开发指南 第三章:绑定语法(1)
查看>>
Java daemon thread 守护线程
查看>>
php实现手机拍照上传头像功能
查看>>
ASP.NET 根据现有动态页面生成静态Html
查看>>
php调试利器Xhprof的安装与使用
查看>>
hadoop: hive 1.2.0 在mac机上的安装与配置
查看>>
TreeView 类 事件
查看>>
java定义和实现接口
查看>>
Excel随机生成数据2
查看>>
修改PHP 加载loaded configuration file 目录
查看>>
windows客户端连接到samba服务器(如何使用samba)
查看>>
shell下有操作json对象的库
查看>>
Xamarin.Android开发实践(九)
查看>>
OpenCV+MFC显示图像
查看>>
第2章 数字之魅——子数组的最大乘积
查看>>
POJ 3414--Pots(BFS+回溯路径)
查看>>
WCF技术剖析之八:ClientBase<T>中对ChannelFactory<T>的缓存机制
查看>>
SQL2008-功能设置
查看>>