欣乐

The eagles are coming!

导航

第十一章 泛型算法

 

code:

 

 

 

 

/*

第11章 泛型算法
11.1 概述
11.2 初窥算法
11.3 再谈迭代器
11.4 泛型算法的结构
11.5 容器特有的算法
小结




第11章 泛型算法 335
11.1 概述 336
11.2 初窥算法 339
11.2.1 只读算法 339
11.2.2 写容器元素的算法 341
11.2.3 对容器元素重新排序的算法 343
11.3 再谈迭代器 347
11.3.1 插入迭代器 348
11.3.2 iostream迭代器 349
11.3.3 反向迭代器 353
11.3.4 const迭代器 355
11.3.5 五种迭代器 356
11.4 泛型算法的结构 358
11.4.1 算法的形参模式 359
11.4.2 算法的命名规范 359
11.5 容器特有的算法 361
小结 362
术语 363

*/


// 11.1 概述 ------------------------------------------------------------------------------------------------------------------

#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
using namespace std;

int main()
{
  vector<int> vec;
  
  // value we'll look for
  int search_value = 42;
  // call find to see if that value is present
  vector < int > ::const_iterator 
  result = find(vec.begin(), vec.end(), search_value);
  // report the result
  cout << "The value " << search_value 
    << (result == vec.end() ? " is not present" : " is present") << endl;
  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  list <int> lst;
  int search_value = 42;
  // call find to look through elements in a list
  list < int > ::const_iterator result = find(lst.begin(), lst.end(),
    search_value);
  cout << "The value " << search_value 
  << (result == lst.end() ? " is not present" : " is present") << endl;

  return 0;
}


// 第一次在数组上使用泛型算法。把数组当容器看。
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  int ia[6] = { 27, 210, 12, 47, 109, 83 };
  int search_value = 83;
  
  int *result = find(ia, ia + 6, search_value);
  cout << "The value " << search_value 
    << (result == ia + 6 ? " is not present" : " is present") << endl;
  
  result = find(ia, ia + 5, search_value); // 搜索子区间
  cout << "The value " << search_value 
    << (result == ia + 5 ? " is not present" : " is present") << endl;  
  
  return 0;
}


// 11.2 初窥算法 --------------------------------------------------------------------------------------------------------------
/*
11.2.1. 只读算法
11.2.2. 写容器元素的算法
11.2.3. 对容器元素重新排序的算法
*/

//11.2.1. 只读算法

// accumulate
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
using namespace std;

int main()
{
  vector<int> vec(3,1);
  // sum the elements in vec starting the summation with the value 42
  int sum = accumulate(vec.begin(), vec.end(), 42);
  cout << sum << endl;
  
  vector<string> v(30,"ha");
  // concatenate elements from v and store in sum
  string s = accumulate(v.begin(), v.end(), string(""));
  cout << s << endl;

  return 0;
}


// in book
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
  list<string> roster1,roster2;
  
  // program for illustration purposes only:
  // there are much faster ways to solve this problem
  size_t cnt = 0;
  list < string > ::iterator it = roster1.begin();
  // look in roster1 for any name also in roster2
  while((it = find_first_of(it, roster1.end(), roster2.begin(), roster2.end()))
    != roster1.end())
  {
    ++cnt;
    // we got a match, increment it to look in the rest of roster1
    ++it;
  }
  cout << "Found " << cnt << " names on both rosters" << endl;
  
  return 0;
}



// 修改,观察输出
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
  list<string> roster1,roster2;
  roster1.insert(roster1.end(),"abc");
  roster1.insert(roster1.end(),"def");
  roster1.insert(roster1.end(),"test"); // 末尾添加,方便观察  
  
  roster2.insert(roster2.end(),"hij");  
  roster2.insert(roster2.end(),"test");
  roster2.insert(roster2.end(),"abc");  

  size_t cnt = 0;
  list < string > ::iterator it = roster1.begin();
  // look in roster1 for any name also in roster2
  while( ( it = find_first_of
    (it, roster1.end(), roster2.begin(), roster2.end()) )
    != roster1.end() ) // 第一次,找roster1中,第一次出现在roster2中的,返回第一个位置,输出"abc"
  {                    // 第二次,在第二个位置开始,找出现在roster2中的,返回"test",输出"test"
    ++cnt;             // 第三次,已经到了roster1.end(),退出循环
    cout << *it << endl;  // 因为是list,所以是顺序查找,这种效率是低的,O(n^2)
    ++it;
  }
  cout << "Found " << cnt << " names on both rosters" << endl;
  
  return 0;
}



// 改进
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
  vector<string> r1;
  r1.insert(r1.end(),"abc");
  r1.insert(r1.end(),"def");
  r1.insert(r1.end(),"test"); // 末尾添加,方便观察  
  
  set<string> r2;
  r2.insert(r2.end(),"hij");  
  r2.insert(r2.end(),"test");
  r2.insert(r2.end(),"abc");  

  size_t cnt = 0;
  vector < string > ::iterator it = r1.begin();
  while( ( it = find_first_of
    (it, r1.end(), r2.begin(), r2.end()) )
    != r1.end() ) // 第一次,找roster1中,第一次出现在roster2中的,返回第一个位置,输出"abc"
  {                    // 第二次,在第二个位置开始,找出现在roster2中的,返回"test",输出"test"
    ++cnt;             // 第三次,已经到了roster1.end(),退出循环
    cout << *it << endl;  // 第一个容器,改成了vector,第二个容器,改成了set,这样 O(nlogn)
    ++it;
  }
  cout << "Found " << cnt << " names on both rosters" << endl;
  
  return 0;
}



//11.2.2. 写容器元素的算法


#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
  vector<int> vec(8);
  fill(vec.begin(), vec.end(), 0); // reset each element to 0
  // set subsequence of the range to 10
  fill(vec.begin(), vec.begin() + vec.size()/2, 10);
  vector<int>::iterator it=vec.begin();
  while( it!=vec.end() )
    cout << *it++ << endl;
  
  return 0;
}


// test越界写入。书里说可能会有运行时错误,但木有发生。总之,不鼓励这么做。。
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
  vector<int> vec(4,0);
  fill(vec.begin(), vec.begin() + 8, 10); // 第一次越界写入
  vector<int>::iterator it=vec.begin();
  while( it!=vec.end() )
    cout << *it++ << endl;
  
  cout << endl;
  fill_n(vec.begin(),18,1); // 第二次越界写入
  it=vec.begin();
  while( it!=vec.end() )
    cout << *it++ << endl;  

  return 0;
}



// 插入迭代器

#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
#include <iterator>
using namespace std;
int main()
{
  vector<int> vec(4,0);
  fill_n(back_inserter(vec),5,8); // 这样不会越界了
  vector<int>::iterator it=vec.begin();
  while( it!=vec.end() )
    cout << *it++ << ' ';

  cout << endl;  
  for(int i=0; i<4; ++i) vec.insert(vec.end(),3); // 4 3
  it=vec.begin(); // 貌似用insert比较容易理解
  while( it!=vec.end() )
    cout << *it++ << ' ';
  cout << endl;      

  return 0;
}


// copy
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;
int main()
{
  list<int> ilst(3,3);
  vector<int> vec(3,0);
  copy(ilst.begin(),ilst.end(),back_inserter(vec));
  
  vector<int>::iterator it=vec.begin();
  while( it!=vec.end() )
    cout << *it++ << ' ';

  cout << endl;
  vector<int> v(ilst.begin(),ilst.end());
  it=v.begin();
  while( it!=v.end() )
    cout << *it++ << ' ';

  return 0;
}


// replace_copy

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;
int main()
{
  list<int> ilst(3,3);
  replace(ilst.begin(),ilst.end(),3,42);
  list<int>::iterator lit=ilst.begin();
  while(lit!=ilst.end())
    cout << *lit++ << ' ';
  cout << endl;
  
  vector<int> vec(3,3);
  replace_copy(ilst.begin(),ilst.end(),
    back_inserter(vec),42,0);
  
  vector<int>::iterator it=vec.begin();
  while( it!=vec.end() )
    cout << *it++ << ' ';

  return 0;
}


//11.2.3. 对容器元素重新排序的算法


// in book
// 输出部分还没完成。
// 谓词部分,还木有全懂。。。。。。
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
// comparison function to be used to sort by word length
bool isShorter(const string &s1, const string &s2)
{
  return s1.size() < s2.size();
}

// determine whether a length of a given word is 6 or more
bool GT6(const string &s)
{
  return s.size() >= 6;
}

int main()
{
  vector < string > words;
  // copy contents of each book into a single vector
  string next_word;
  while(cin >> next_word)
  {
    // insert next book's contents at end of words
    words.push_back(next_word);
  }
  // sort words alphabetically so we can find the duplicates
  sort(words.begin(), words.end());
  /* eliminate duplicate words:
   * unique reorders words so that each word appears once in the
   *       front portion of words and returns an iterator one past the unique range;
   * erase uses a vector operation to remove the nonunique elements
   */
  vector < string > ::iterator end_unique = unique(words.begin(), words.end());
  words.erase(end_unique, words.end());
  // sort words by size, but maintain alphabetic order for words of the same size
  stable_sort(words.begin(), words.end(), isShorter);
  vector < string > ::size_type wc = count_if(words.begin(), words.end(), GT6);
  cout << wc << " " << make_plural(wc, "word", "s")  // later...
    << " 6 characters or longer" << endl;
  
  return 0;
}



// 11.3 再谈迭代器 ------------------------------------------------------------------------------------------------------------
/*
11.3.1. 插入迭代器
11.3.2. iostream Iterators
11.3.3. Reverse Iterators
11.3.4. const Iterators
11.3.5. 五种迭代器
*/


// 11.3.1. 插入迭代器

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

int main()
{
  vector<int> ivec(3,100);
  list<int> ilst(3,42);
  ilst.insert(ilst.begin(),1);
  
  // position an iterator into ilst
  list < int > ::iterator it = find(ilst.begin(), ilst.end(), 42);
  // insert replaced copies of ivec at that point in ilst
  replace_copy(ivec.begin(), ivec.end(), 
               inserter(ilst, it), 100, 0);
  
  it=ilst.begin();
  while( it!=ilst.end() )
    cout << *it++ << ' ';
  cout << endl;
  
  return 0;
}


// insert
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
  list < int > ilst, ilst2, ilst3; // empty lists
  
  // after this loop ilst contains: 3 2 1 0
  for(list < int > ::size_type i = 0; i != 4; ++i)
    ilst.push_front(i);

  // after copy ilst2 contains: 0 1 2 3
  copy(ilst.begin(), ilst.end(), front_inserter(ilst2));
  
  // after copy, ilst3 contains: 3 2 1 0
  copy(ilst.begin(), ilst.end(), inserter(ilst3, ilst3.begin()));

  list < int > ::iterator it;  

  it=ilst.begin();
  while(it != ilst.end())
    cout <<  *it++ << ' ';
  cout << endl;

  it=ilst2.begin();
  while(it != ilst2.end())
    cout <<  *it++ << ' ';
  cout << endl;

  it=ilst3.begin();
  while(it != ilst3.end())
    cout <<  *it++ << ' ';
  cout << endl;

  return 0;
}



// 11.3.2. iostream Iterators

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

int main()
{
  vector<int> vec;
  istream_iterator < int > in_iter(cin); // read ints from cin
  istream_iterator < int > eof; // istream "end" iterator
  // read until end of file, storing what was read in vec
  while(in_iter != eof)
  // increment advances the stream to the next value
  // dereference reads next value from the istream
    vec.push_back(*in_iter++);

  vector < int > ::iterator it;
  it = vec.begin();
  while(it != vec.end())
    cout <<  *it++ << ' ';
  cout << endl;

  return 0;
}


// in book
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

int main()
{
  istream_iterator < int > in_iter(cin); // read ints from cin
  istream_iterator < int > eof; // istream "end" iterator
  vector<int> vec(in_iter, eof);  // construct vec from an iterator range

  vector < int > ::iterator it;
  it = vec.begin();
  while(it != vec.end())
    cout <<  *it++ << ' ';
  cout << endl;

  return 0;
}


// 运行貌似不太正常
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
  // write one string per line to the standard output
  ostream_iterator < string > out_iter(cout, "\n");
  
  // read strings from standard input and the end iterator
  istream_iterator < string > in_iter(cin), eof;
  
  // read until eof and write what was read to the standard output
  while(in_iter != eof)
  // write value of in_iter to standard output
  // and then increment the iterator to get the next value from cin
    *out_iter++ =  *in_iter++;

  return 0;
}




#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
  istream_iterator < int > cin_it(cin); // reads ints from cin
  istream_iterator < int > end_of_stream; // end iterator value
  
  // initialize vec from the standard input:
  vector < int > vec(cin_it, end_of_stream);
  sort(vec.begin(), vec.end());
  
  // writes ints to cout using " " as the delimiter
  ostream_iterator < int > output(cout, " ");
  
  // write only the unique elements in vec to the standard output
  unique_copy(vec.begin(), vec.end(), output);
  
  return 0;
}

// 23 109 45 89 6 34 12 90 34 23 56 23 8 89 23



// 11.3.3. Reverse Iterators


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
  vector < int > vec;
  for(vector < int > ::size_type i = 0; i != 10; ++i)
    vec.push_back(i);
  // elements are 0,1,2,...9

  // reverse iterator of vector from back to front
  vector < int > ::reverse_iterator r_iter;
  for(r_iter = vec.rbegin();  // binds r_iter to last element
    r_iter != vec.rend();  // rend refers 1 before 1st element
    ++r_iter)
  // decrements iterator one element
    cout <<  *r_iter << endl;
  // prints 9,8,7,...0

  // sorts vec in "normal" order
  sort(vec.begin(), vec.end());
  
  // sorts in reverse: puts smallest element at the end of vec
  sort(vec.rbegin(), vec.rend());
  
  return 0;
}



#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
  string line("FIRST,MIDDLE,LAST");
  
  // find first element in a comma-separated list
  string::iterator comma = find(line.begin(), line.end(), ',');
  cout << string(line.begin(), comma) << endl;
  
  // find last element in a comma-separated list
  string::reverse_iterator rcomma = find(line.rbegin(), line.rend(), ',');
  // wrong: will generate the word in reverse order
  cout << string(line.rbegin(), rcomma) << endl;
  
  // ok: get a forward iterator and read to end of line
  cout << string(rcomma.base(), line.end()) << endl;

  return 0;
}


// 11.3.4. const Iterators

// 11.3.5. 五种迭代器



// 11.4 泛型算法的结构 --------------------------------------------------------------------------------------------------------


// 11.5 容器特有的算法 --------------------------------------------------------------------------------------------------------

 

 

 

 

TOP

 

posted on 2014-11-10 20:34  欣乐  阅读(174)  评论(0编辑  收藏  举报