zoukankan      html  css  js  c++  java
  • 作业8-STL1作业

    1.goodcopy

    编写GoodCopy类模板,使得程序按指定方式输出

     1 #include <iostream>
     2 using namespace std;
     3 
     4 template <class T>
     5 struct GoodCopy {
     6     void operator()(T*s,T*e,T*to) {
     7         for( ; e != s; e--){
     8             *(to+(e-s)-1) = *(e-1);  //注意e-s要加括号 
     9         } 
    10     }
    11 };
    12 
    13 int a[200];
    14 int b[200];
    15 string c[200];
    16 string d[200];
    17 
    18 template <class T>
    19 void Print(T s,T e) {
    20     for(; s != e; ++s)
    21         cout << * s << ",";
    22     cout << endl;
    23 }
    24 
    25 int main()
    26 {
    27     int t;
    28     cin >> t;
    29     while( t -- ) {
    30         int m ;
    31         cin >> m;
    32         for(int i = 0;i < m; ++i)
    33             cin >> a[i];
    34         GoodCopy<int>()(a,a+m,b); //GoodCopy<int>()产生了一个临时对象,通过产生临时对象调用重载运算符 
    35         Print(b,b+m);
    36         GoodCopy<int>()(a,a+m,a+m/2); //从中间开始复制,要防止覆盖 
    37         Print(a+m/2,a+m/2 + m);
    38 
    39         for(int i = 0;i < m; ++i)
    40             cin >> c[i];
    41         GoodCopy<string>()(c,c+m,d);
    42         Print(c,c+m);
    43         GoodCopy<string>()(c,c+m,c+m/2);
    44         Print(c+m/2,c+m/2 + m);
    45     }
    46     return 0;
    47 }

    备注:函数对象也叫仿函数。如果一个类将()运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象。函数对象是一个对象,但是使用的形式看起来像函数调用,实际上也执行了函数调用,因而得名。其实就是一个对象,重载了小括号。然后调用的时候有两种方法,一个是GoodCopy<int>a; a(a,a+m,b),这种方法就是要命名一个GoodCopy对象,也可以像这道题里建一个临时对象。还有就是因为有从中间开始复制的情况,所以要倒着复制,要用e--来遍历。

    2.按距离排序

     1 #include <iostream>
     2 #include <cmath>
     3 #include <algorithm>
     4 #include <string>
     5 using namespace std;
     6 template <class T1,class T2>
     7 struct Closer {
     8 // 在此处补充你的代码
     9     T1 n;
    10     T2 cmp;
    11     Closer(T1 n_, T2 cmp_):n(n_),cmp(cmp_){}
    12     bool operator()(const T1 & a, const T1 & b){
    13         if(cmp(a,n)==cmp(b,n)) return a<b;
    14         return cmp(a,n)<cmp(b,n); 
    15     } 
    16 }; //函数对象 
    17 
    18 int Distance1(int n1,int n2) {
    19     return abs(n1-n2);
    20 }
    21 int Distance2(const string & s1, const string & s2)
    22 {
    23     return abs((int)s1.length()- (int) s2.length());
    24 }
    25 int a[10] = { 0,3,1,4,7,9,20,8,10,15};
    26 string b[6] = {"American","Jack","To","Peking","abcdefghijklmnop","123456789"};
    27 int main()
    28 {
    29     int n;string s;
    30     while( cin >> n >> s ) {//sort,判断x是否比y靠前,就看cmp(x, y)是否为true 
    31         sort(a,a+10,Closer<int ,int (*)(int ,int)> (n,Distance1)); //函数指针  
    32         for(int i = 0;i < 10; ++i)
    33             cout << a[i] << "," ;
    34         cout << endl;
    35         sort(b,b+6,Closer<string,int (*)(const string &,const string &  )> (s,Distance2)); 
    36         for(int i = 0;i < 6; ++i)
    37             cout << b[i] << "," ;
    38         cout << endl;
    39     }
    40     return 0;
    41 }

    备注:Closer<int ,int (*)(int ,int)> (n,Distance1)这是一个对象,int(*)(int ,int)是一个函数指针。sort函数,判断x是否比y靠前,就看cmp(x, y)是否为true .

    3.很难蒙混过关的CArray3d三维数组模板类

     1 #include <iostream>
     2 #include <iomanip> 
     3 #include <cstring>
     4 using namespace std;
     5 template <class T>
     6 class CArray3D
     7 {
     8 // 在此处补充你的代码
     9 public: //内部类一般是public 
    10     class CArray2D{ 
    11     public:
    12         int y,z;
    13         T * p;
    14         void set(int m, int n){
    15             y = m, z = n;
    16             p = new T[m*n];
    17         }
    18         T * operator[](int k){
    19             return p+k*z;
    20         }
    21         operator T*(){ //强制转换成指针 
    22             return this->p; 
    23         }
    24     };
    25     int x;
    26     CArray2D * array;
    27     CArray3D(int x_, int y_, int z_):x(x_){
    28         array = new CArray2D[x_]; //有参构造函数不能直接用于数组的构造
    29         for(int i = 0; i < x_; i++)
    30             array[i].set(y_, z_); 
    31     }
    32     CArray2D & operator[](int n){
    33         return array[n];
    34     }
    35 };
    36 
    37 CArray3D<int> a(3,4,5);
    38 CArray3D<double> b(3,2,2);
    39 void PrintA()
    40 {
    41     for(int i = 0;i < 3; ++i) {
    42         cout << "layer " << i << ":" << endl;
    43         for(int j = 0; j < 4; ++j) {
    44             for(int k = 0; k < 5; ++k) 
    45                 cout << a[i][j][k] << "," ;
    46             cout << endl;
    47         }
    48     }
    49 }
    50 void PrintB()
    51 {
    52     for(int i = 0;i < 3; ++i) {
    53         cout << "layer " << i << ":" << endl;
    54         for(int j = 0; j < 2; ++j) {
    55             for(int k = 0; k < 2; ++k) 
    56                 cout << b[i][j][k] << "," ;
    57             cout << endl;
    58         }
    59     }
    60 }
    61 
    62 int main()
    63 {
    64 
    65     int No = 0;
    66     for( int i = 0; i < 3; ++ i ) {
    67         a[i];
    68         for( int j = 0; j < 4; ++j ) {
    69             a[j][i];
    70             for( int k = 0; k < 5; ++k )
    71                 a[i][j][k] = No ++;
    72             a[j][i][i];    
    73         }
    74     }
    75     PrintA();
    76     memset(a[1],-1 ,20*sizeof(int));    
    77     memset(a[1],-1 ,20*sizeof(int));
    78     PrintA(); 
    79     memset(a[1][1],0 ,5*sizeof(int));    
    80     PrintA();
    81 
    82     for( int i = 0; i < 3; ++ i )
    83         for( int j = 0; j < 2; ++j )
    84             for( int k = 0; k < 2; ++k )
    85                 b[i][j][k] = 10.0/(i+j+k+1);
    86     PrintB();
    87     int n = a[0][1][2];
    88     double f = b[0][1][1];
    89     cout << "****" << endl;
    90     cout << n << "," << f << endl;
    91         
    92     return 0;
    93 }

    备注:这道题要注意看提示:

    建议做法:
    1. a[i][j][k] 这个表达式的第一个[]返回一个内部类的对象,该内部类也重载了[],且返回值为指针。
    2. 必要时需重载对象到指针的强制类型转换运算符

    内部类也叫嵌套类https://blog.csdn.net/liyuanbhu/article/details/43897979,详情可以看这里。我本来想试图直接用构造函数直接构造CArray2D * array;但发现必须得些for循环那一行来用set初始化,因为new调用的只能是无参构造函数。

    memset里的a[1]需要是一个地址,a[1]本身是一个CArray2D,所以要强制类型转换成指针。

    4.函数对象的过滤器

     1 #include <iostream>
     2 #include <vector>
     3 using namespace std;
     4 
     5 struct A {
     6     int v;
     7     A() { }
     8     A(int n):v(n) { };
     9     bool operator<(const A & a) const {
    10         return v < a.v;
    11     }
    12 };
    13 // 在此处补充你的代码
    14 template <class T>
    15 struct FilterClass{
    16     T m, n; //这里不能是int 
    17     FilterClass(int mm, int nn):m(mm),n(nn){} //注意数据类型 
    18     bool operator()(T a){
    19         return (m<a)&&(a<n); //必须是小于号,因为只重载了小于号 
    20     }
    21 };
    22 
    23 template <class T>
    24 void Print(T s,T e)
    25 {
    26     for(;s!=e; ++s)
    27         cout << *s << ",";
    28     cout << endl;
    29 }
    30 template <class T1, class T2,class T3>
    31 T2 Filter( T1 s,T1 e, T2 s2, T3 op) 
    32 {
    33     for(;s != e; ++s) {
    34         if( op(*s)) { //这个函数的参数就是*s 
    35             * s2 = * s;
    36             ++s2;
    37         }
    38     }
    39     return s2;
    40 }
    41 
    42 ostream & operator <<(ostream & o,A & a)
    43 {
    44     o << a.v;
    45     return o;
    46 }
    47 vector<int> ia;
    48 vector<A> aa; 
    49 int main()
    50 {
    51     int m,n;
    52     while(cin >> m >> n) {
    53         ia.clear();
    54         aa.clear(); 
    55         int k,tmp;
    56         cin >> k;
    57         for(int i = 0;i < k; ++i) {
    58             cin >> tmp; 
    59             ia.push_back(tmp);
    60             aa.push_back(tmp); 
    61         }
    62         vector<int> ib(k);
    63         vector<A> ab(k);
    64         vector<int>::iterator p =  Filter(ia.begin(),ia.end(),ib.begin(),FilterClass<int>(m,n)); //一个临时的函数对象,可以理解成一个函数名 
    65         Print(ib.begin(),p);
    66         vector<A>::iterator pp = Filter(aa.begin(),aa.end(),ab.begin(),FilterClass<A>(m,n));
    67         Print(ab.begin(),pp);
    68         
    69     }
    70     return 0;
    71 }

    备注:两个注意的地方。一个是重载的是小于号,因此只能用小于号来比较A类对象。二是注意FilterClass里的变量类型,需得是T类,不能是int。

    5.白给的list排序

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <list>
     5 using namespace std;
     6 int main()
     7 {    
     8     double a[] = {1.2,3.4,9.8,7.3,2.6};
     9     list<double> lst(a,a+5);
    10     lst.sort(//list只能用自己的sort 
    11 // 在此处补充你的代码
    12     greater<int>() 
    13 );
    14     
    15     for(list<double>::iterator i  = lst.begin(); i != lst.end(); ++i) 
    16         cout << * i << "," ;
    17     return 0;
    18 }

    list只能用自己的sort来排序,只有两种sort,一种无参一种有参。这里就是填了个sort的参数:greater<int>()这个函数对象

    6.我自己的ostream_iterator

     1 #include <iostream>
     2 #include <list>
     3 #include <string>
     4 using namespace std;
     5 
     6 template <class T1,class T2>
     7 void Copy(T1 s,T1 e, T2 x)
     8 {
     9     for(; s != e; ++s,++x)
    10         *x = *s;
    11 }
    12 
    13  
    14 template<class T>
    15 class myostream_iteraotr
    16 {
    17 // 在此处补充你的代码
    18     ostream & out;
    19     string s;
    20 public: //总是忘记public…… 
    21     myostream_iteraotr(ostream & out_, string s_):out(out_),s(s_){}
    22     void operator++(){}
    23     myostream_iteraotr& operator*(){return *this;} //这俩其实都没啥用,但这里一定要返回的是 myostream_iteraotr,因为等于号是作用在*x上的 
    24     void operator=(T a){
    25         out<<a<<s;
    26     } 
    27 };
    28 
    29 
    30 int main()
    31 {    const int SIZE = 5;
    32     int a[SIZE] = {5,21,14,2,3};
    33     double b[SIZE] = { 1.4, 5.56,3.2,98.3,3.3};
    34     list<int> lst(a,a+SIZE);
    35     myostream_iteraotr<int> output(cout,",");
    36     Copy( lst.begin(),lst.end(),output); 
    37     cout << endl;
    38     myostream_iteraotr<double> output2(cout,"--");
    39     Copy(b,b+SIZE,output2);
    40     return 0;
    41 }

    备注:可以和上一节的istream_iterator对比着看。区别在于++不执行任何操作,=号执行输出,同时要注意*的返回值一定是myostream_iteraotr类,以及这个拼写是奇怪的……

  • 相关阅读:
    基于索引的MySQL优化
    SQL优化:
    in的对象选择(子查询还是List集合),in 的优化,in与exists
    嵌套查询及其作用域:
    group by实现原理及其作用
    批量打回未报bug修复
    解析Job,bpmn文件的小项目总结
    用户短时间内多次提交与保存带来的问题
    嵌套连接
    多范围读取优化
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/12616541.html
Copyright © 2011-2022 走看看