C++泛型編程(2)--經過排序和查找元素理解迭代器

許多C++開源庫(stl,opencv,ros和blas等)都使用了大量的泛型編程的思想,若是不理解這些思想,將很難看懂代碼,而《泛型編程與STL》一書對理解泛型編程思想很是的有幫助,這裏整理第二章的一些實現代碼。node

1.排序元素ios

#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.查找元素app

#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;
}

運行結果this

****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

參考資料spa

[1].泛型編程與STL 侯捷 - 2003 - 中國電力出版社,第二章指針

相關文章
相關標籤/搜索