• 第十一章 泛型算法


     

    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, "
    ");
      
      // 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

  • 相关阅读:
    智慧园区数字孪生平台GIS+三维可视化的研究
    树莓派联通家庭宽带端口映射
    NetCore 5.0 Dokcer中发布报NU3028、NU3037
    django导入导出excel实践
    MySQL JSON类型
    业务、设计模式、算法
    VIM 简单教程
    k8s go-client 使用简介
    如何健壮你的后端服务
    公共dto打包时按条件导出实现feignclient接口的bean,解决feign.Feign$Builder类找不到的问题
  • 原文地址:https://www.cnblogs.com/xin-le/p/4088100.html
Copyright © 2020-2023  润新知