C++泛型编程(2)--通过排序和查找元素理解迭代器
许多C++开源库(stl,opencv,ros和blas等)都使用了大量的泛型编程的思想,如果不理解这些思想,将很难看懂代码,而《泛型编程与STL》一书对理解泛型编程思想非常的有帮助,这里整理第二章的一些实现代码。
1.排序元素
#include <iostream> #include <vector> #include <algorithm> #include <ostream> #include <iterator> using namespace std; int main(int argc, char** argv) { vector<string> V; string tmp; while (getline(cin, tmp)) { if (tmp == "") break; // 回车结束 V.push_back(tmp); } // sort(V.begin(), V.end());// 升序 sort(V.begin(), V.end(), greater<string>()); // 降序 copy(V.begin(), V.end(), ostream_iterator<string>(cout, "\n")); return 0; }
运行结果
输入: 1 2 3 4 5 6 7 排序输出: 7 6 5 4 3 2 1
2.查找元素
#include <string.h> #include <iostream> #include <vector> #include <algorithm> #include <ostream> #include <iterator> using namespace std; // 通常的查找方法,通过'\0'来结束查找 char* strchr(char *s, int c) { while (*s != '\0' && *s != c) { ++s; } return *s == c ? s : (char*) 0; // #define NULL (char*) 0 } // C 改进版本的查找方法,引入了range的概念[first, last), // 通过比较指针first = last来结束查找 char* find1(char* first, char* last, int value) { while (first != last && *first != value) ++first; return first; } // C++ 模板方法查找,数据类型作为模板参数传入 template<class T> T* find2(T* first, T* last, T value) { while (first != last && *first != value) ++first; return first; } // C++ 模板方法查找,访问器和数据类型都作为模板参数传入, // 相较于find2,find具有更一般性。其很好地解决了以下问题: // 1.审视元素;2.移动到下一个元素;3.检查是否已经处理完成所有元素;4.元素比较 template<class Iterator, class T> Iterator find3(Iterator first, Iterator last, const T& value) { while (first != last && *first != value) { ++first; } return first; } // 链表查找 struct int_node { int value; int_node* next; }; // 链表无法满足 操作符的比较,因此通过一个外覆类实现++ == ->等操作符号的重载 template<class Node> struct node_wrapper { Node* ptr; node_wrapper(Node* p = 0) : ptr(p) { } // * Node& operator *() const { return *ptr; } // 访问-> Node* operator ->() const { return ptr; } // 前置累加 node_wrapper operator++() { ptr = ptr->next; return *this; } // 后置累加 node_wrapper operator ++(int) { node_wrapper tmp = *this; ++*this; return tmp; } // 相等判断 bool operator ==(const node_wrapper& i) const { return ptr == i.ptr; } // 非相等判断 bool operator !=(const node_wrapper& i) const { return ptr != i.ptr; } }; // template funtion, object function template<class Node, class T> bool operator !=(const Node& node, T value) { if (node.value != value) return true; return false; } int main(int argc, char** argv) { char pat = 'x'; char str[10] = "horsetail"; int str_size = strlen(str); cout << "****Task1: to find '" << pat << "' from \"" << str << "\"" << endl; // 通常的查找方法,通过'\0'来结束查找 cout << "----testing strchr----" << endl; char* res = strchr(str, (int) pat); // to find if (res != NULL) cout << "found " << pat << endl; else cout << "not found " << pat << endl; // C 改进版本的查找方法,引入了range的概念[first, last), // 通过比较指针first = last来结束查找 cout << "----testing find1----" << endl; res = find1(str, str + str_size, (int) pat); // to find if (res != str + str_size) cout << "found " << pat << endl; else cout << "not found " << pat << endl; // C++ 模板方法查找,数据类型作为模板参数传入 cout << "----testing find2----" << endl; res = find2(str, str + str_size, pat); // to find if (res != str + str_size) cout << "found " << pat << endl; else cout << "not found " << pat << endl; // C++ 模板方法查找,访问器和数据类型都作为模板参数传入, // 相较于find2,find具有更一般性。其很好地解决了以下问题: // 1.审视元素;2.移动到下一个元素;3.检查是否已经处理完成所有元素;4.元素比较 cout << "----testing find3----" << endl; res = find3(str, str + str_size, pat); // to find if (res != str + str_size) cout << "found " << pat << endl; else cout << "not found " << pat << endl; // 链表查找,链表无法满足 操作符的比较,因此通过一个外覆类实现++ == ->等操作符号的重载 int value = 6; int link_size = 10; cout << endl; cout << "****Task2: to find " << value << " from {0,1,2,3,...,10}" << endl; cout << "----testing link int_node with find3----" << endl; int_node* head_node = new int_node(); head_node->value = 0; head_node->next = 0; int_node* pnode = head_node; for (int i = 1; i < link_size; i++) {// link contain {0,1,2,3,4,5,6,...} int_node* node = new int_node(); node->value = i; node->next = 0; pnode->next = node; pnode = node; } node_wrapper<int_node> first(head_node); node_wrapper<int_node> last(0); node_wrapper<int_node> result = find3(first, last, value); // to find if (result != last) cout << "found " << value << endl; else cout << "not found " << value << endl; return 0; }
运行结果
****Task1: to find 'x' from "horsetail" ----testing strchr---- not found x ----testing find1---- not found x ----testing find2---- not found x ----testing find3---- not found x ****Task2: to find 6 from {0,1,2,3,...,10} ----testing link int_node with find3---- found 6
参考资料
[1].泛型编程与STL 侯捷 - 2003 - 中国电力出版社,第二章
Make Change - Focus on Computer Vision and Pattern Recognition
版权声明:本文为博主原创文章,未经博主允许不得转载
版权声明:本文为博主原创文章,未经博主允许不得转载