当前位置:   article > 正文

程序设计与算法(三)C++面向对象程序设计 第八周题解(仿函数)_程序填空输出指定结果 #include #include u

程序填空输出指定结果 #include #include using namespace s

001:goodcopy

总时间限制: 

1000ms

内存限制: 

65536kB

// 在此处补充你的代码

描述

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

  1. #include <iostream>
  2. using namespace std;
  3. template <class T>
  4. struct GoodCopy {
  1. };
  2. int a[200];
  3. int b[200];
  4. string c[200];
  5. string d[200];
  6. template <class T>
  7. void Print(T s,T e) {
  8. for(; s != e; ++s)
  9. cout << * s << ",";
  10. cout << endl;
  11. }
  12. int main()
  13. {
  14. int t;
  15. cin >> t;
  16. while( t -- ) {
  17. int m ;
  18. cin >> m;
  19. for(int i = 0;i < m; ++i)
  20. cin >> a[i];
  21. GoodCopy<int>()(a,a+m,b);
  22. Print(b,b+m);
  23. GoodCopy<int>()(a,a+m,a+m/2);
  24. Print(a+m/2,a+m/2 + m);
  25. for(int i = 0;i < m; ++i)
  26. cin >> c[i];
  27. GoodCopy<string>()(c,c+m,d);
  28. Print(c,c+m);
  29. GoodCopy<string>()(c,c+m,c+m/2);
  30. Print(c+m/2,c+m/2 + m);
  31. }
  32. return 0;
  33. }

输入

第一行是整数 t,表示数据组数
每组数据:
第一行是整数 n , n < 50
第二行是 n 个整数 
第三行是 n 个字符串

输出

将输入的整数原序输出两次,用","分隔
然后将输入的字符串原序输出两次,也用 ","分隔

样例输入

  1. 2
  2. 4
  3. 1 2 3 4
  4. Tom Jack Marry Peking
  5. 1
  6. 0
  7. Ted

样例输出

  1. 1,2,3,4,
  2. 1,2,3,4,
  3. Tom,Jack,Marry,Peking,
  4. Tom,Jack,Marry,Peking,
  5. 0,
  6. 0,
  7. Ted,
  8. Ted,

来源

Guo Wei

 

这是典型的C++ 仿函数和内存重叠拷贝问题。

仿函数(functor),就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。

在我们写代码时有时会发现有些功能实现的代码,会不断的在不同的成员函数中用到,但是又不好将这些代码独立出来成为一个类的一个成员函数。但是又很想复用这些代码。写一个公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数,也不是很好维护。这时就可以用仿函数了,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。这样就免去了对一些公共变量的全局化的维护了。又可以使那些代码独立出来,以便下次复用。而且这些仿函数,还可以用关联,聚合,依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理(这点可能是它相对于函数最显著的优点了)。如果在配合上模板技术和policy编程思想,那就更是威力无穷了,大家可以慢慢的体会。

 

  1. #include <iostream>
  2. using namespace std;
  3. template <class T>
  4. struct GoodCopy {
  5. // 在此处补充你的代码
  6. public:
  7. void operator() (T* begin, T* end, T* another){
  8. if (another < end) {
  9. for (auto it = end - 1; it >= begin; it--) {
  10. *(another +(it-begin))= *it;
  11. }
  12. }
  13. else {
  14. for (auto it = begin; it != end; ++it) {
  15. *another++ = *it;
  16. }
  17. }
  18. }
  19. };
  20. int a[200];
  21. int b[200];
  22. string c[200];
  23. string d[200];
  24. template <class T>
  25. void Print(T s, T e) {
  26. for (; s != e; ++s)
  27. cout << *s << ",";
  28. cout << endl;
  29. }
  30. int main()
  31. {
  32. int t;
  33. cin >> t;
  34. while (t--) {
  35. int m;
  36. cin >> m;
  37. for (int i = 0; i < m; ++i)
  38. cin >> a[i];
  39. GoodCopy<int>()(a, a + m, b);
  40. Print(b, b + m);
  41. GoodCopy<int>()(a, a + m, a + m / 2);
  42. Print(a + m / 2, a + m / 2 + m);
  43. for (int i = 0; i < m; ++i)
  44. cin >> c[i];
  45. GoodCopy<string>()(c, c + m, d);
  46. Print(c, c + m);
  47. GoodCopy<string>()(c, c + m, c + m / 2);
  48. Print(c + m / 2, c + m / 2 + m);
  49. }
  50. return 0;
  51. }

函数指针

003:简单的Filter

总时间限制: 

1000ms

 

内存限制: 

65536kB

// 在此处补充你的代码

描述

编写Filter模板,使得程序产生指定输出 不得编写 Filter函数

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  1. bool LargerThan2(int n)
  2. {
  3. return n > 2;
  4. }
  5. bool LongerThan3(string s)
  6. {
  7. return s.length() > 3;
  8. }
  9. string as1[5] = {"Tom","Mike","Jack","Ted","Lucy"};
  10. string as2[5];
  11. int a1[5] = { 1,2,3,4,5};
  12. int a2[5];
  13. int main() {
  14. string * p = Filter(as1,as1+5,as2,LongerThan3);
  15. for(int i = 0;i < p - as2; ++i)
  16. cout << as2[i];
  17. cout << endl;
  18. int * p2 = Filter(a1,a1+5,a2,LargerThan2);
  19. for(int i = 0;i < p2-a2; ++i)
  20. cout << a2[i] << ",";
  21. return 0;
  22. }

输入

输出

MikeJackLucy
3,4,5,

样例输入

样例输出

  1. MikeJackLucy
  2. 3,4,5,

来源

Guo Wei

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. template<class T>
  5. T* Filter(T* start, T* end, T* begin, bool(*func)(T))
  6. {
  7. for (auto it = start; it < end; ++it) {
  8. if (func(*it)) {
  9. *begin = *it;
  10. begin++;
  11. }
  12. }
  13. return begin;
  14. }
  15. bool LargerThan2(int n)
  16. {
  17. return n > 2;
  18. }
  19. bool LongerThan3(string s)
  20. {
  21. return s.length() > 3;
  22. }
  23. string as1[5] = {"Tom","Mike","Jack","Ted","Lucy"};
  24. string as2[5];
  25. int a1[5] = { 1,2,3,4,5};
  26. int a2[5];
  27. int main() {
  28. string * p = Filter(as1,as1+5,as2,LongerThan3);
  29. for(int i = 0;i < p - as2; ++i)
  30. cout << as2[i];
  31. cout << endl;
  32. int * p2 = Filter(a1,a1+5,a2,LargerThan2);
  33. for(int i = 0;i < p2-a2; ++i)
  34. cout << a2[i] << ",";
  35. return 0;
  36. }

 

004:函数对象的过滤器

总时间限制: 

1000ms

 

内存限制: 

65536kB

// 在此处补充你的代码

描述

程序填空输出指定结果

#include <iostream>
#include <vector>
using namespace std;


struct A {
	int v;
	A() { }
	A(int n):v(n) { };
	bool operator<(const A & a) const {
		return v < a.v;
	}
};
template <class T>
void Print(T s,T e)
{
	for(;s!=e; ++s)
		cout << *s << ",";
	cout << endl;
}
template <class T1, class T2,class T3>
T2 Filter( T1 s,T1 e, T2 s2, T3 op) 
{
	for(;s != e; ++s) {
		if( op(*s)) {
			* s2 = * s;
			++s2;
		}
	}
	return s2;
}

ostream & operator <<(ostream & o,A & a)
{
	o << a.v;
	return o;
}
vector<int> ia;
vector<A> aa; 
int main()
{
	int m,n;
	while(cin >> m >> n) {
		ia.clear();
		aa.clear(); 
		int k,tmp;
		cin >> k;
		for(int i = 0;i < k; ++i) {
			cin >> tmp; 
			ia.push_back(tmp);
			aa.push_back(tmp); 
		}
		vector<int> ib(k);
		vector<A> ab(k);
		vector<int>::iterator p =  Filter(ia.begin(),ia.end(),ib.begin(),FilterClass<int>(m,n));
		Print(ib.begin(),p);
		vector<A>::iterator pp = Filter(aa.begin(),aa.end(),ab.begin(),FilterClass<A>(m,n));
		Print(ab.begin(),pp);
		
	}
	return 0;
}

输入

多组数据
每组数据两行 

第一行是两个整数 m 和 n
第二行先是一个整数k ,然后后面跟着k个整数

输出

对每组数据,按原顺序输出第二行的后k个整数中,大于m且小于n的数
输出两遍 
数据保证一定能找到符合要求的整数

样例输入

1 3
1 2
2 8
5 1 2 3 4 9

样例输出

2,
2,
3,4,
3,4,

来源

Guo Wei

 

这道题目有一点难度,注意先要看函数

  1. template <class T1, class T2, class T3>
  2. T2 Filter(T1 s, T1 e, T2 s2, T3 op)
  3. {
  4. for (; s != e; ++s) {
  5. if (op(*s)) {
  6. *s2 = *s;
  7. ++s2;
  8. }
  9. }
  10. return s2;
  11. }

三个模板参数,最后一个参数是一个仿函数

传进去的是一个类对象,执行的是运算符重载,这个类对象有一个构造函数

  1. template <class T>
  2. struct FilterClass {
  3. T m, n;
  4. FilterClass(T a, T b) :m(a), n(b) {}
  5. bool operator()(T s) {
  6. return (m < s) && (s < n);
  7. }
  8. };

005:白给的list排序

总时间限制: 

1000ms

 

内存限制: 

65536kB

// 在此处补充你的代码

描述

程序填空,产生指定输出

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
int main()
{	
	double a[] = {1.2,3.4,9.8,7.3,2.6};
	list<double> lst(a,a+5);
	lst.sort(
);
	
	for(list<double>::iterator i  = lst.begin(); i != lst.end(); ++i) 
		cout << * i << "," ;
    return 0;
}

输入

输出

9.8,7.3,3.4,2.6,1.2,

样例输入

样例输出

同输入 

来源

Guo Wei

 

这里按降序排序,使用了一个仿函数,greater

  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(greater<double>()
  11. // 在此处补充你的代码
  12. );
  13. for (list<double>::iterator i = lst.begin(); i != lst.end(); ++i)
  14. cout << *i << ",";
  15. return 0;
  16. }

002:按距离排序

总时间限制: 

1000ms

 

内存限制: 

65536kB

// 在此处补充你的代码

描述

程序填空,输出指定结果

#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
template <class T1,class T2>
struct Closer {
};

int Distance1(int n1,int n2) {
	return abs(n1-n2);
}
int Distance2(const string & s1, const string & s2)
{
	return abs((int)s1.length()- (int) s2.length());
}
int a[10] = { 0,3,1,4,7,9,20,8,10,15};
string b[6] = {"American","Jack","To","Peking","abcdefghijklmnop","123456789"};
int main()
{
	int n;string s;
	while( cin >> n >> s ) {
		sort(a,a+10,Closer<int ,int (*)(int ,int)> (n,Distance1));
		for(int i = 0;i < 10; ++i)
			cout << a[i] << "," ;
		cout << endl;
		sort(b,b+6,Closer<string,int (*)(const string &,const string &  )> (s,Distance2)); 
		for(int i = 0;i < 6; ++i)
			cout << b[i] << "," ;
		cout << endl;
	}
	return 0;
}

输入

多组数据,每组一行,是一个整数n和一个字符串s

输出

定义两个整数的距离为两个整数差的绝对值
定义两个字符串的距离为两个字符串长度差的绝对值 

对每组数据:
对数组a按和n的距离从小到大排序后输出。距离相同的,值小的排在前面。
然后对数组b,按照和s的距离从小到大输出。距离相同的,字典序小的排在前面

样例输入

2 a123456
4 a12345

样例输出

1,3,0,4,7,8,9,10,15,20,
American,Peking,123456789,Jack,To,abcdefghijklmnop,
4,3,1,7,0,8,9,10,15,20,
Peking,American,Jack,123456789,To,abcdefghijklmnop,

 

这个也是标准的STL仿函数的例子练习

  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 a;
  10. T2 func;
  11. Closer(T1 a_, T2 func_):a(a_),func(func_){}
  12. bool operator ()(T1 a1, T1 a2) {
  13. if (func(a1, a) == func(a2, a)) {
  14. return a1 < a2;
  15. }
  16. else return func(a1, a) < func(a2, a);
  17. }
  18. };
  19. int Distance1(int n1, int n2) {
  20. return abs(n1 - n2);
  21. }
  22. int Distance2(const string& s1, const string& s2)
  23. {
  24. return abs((int)s1.length() - (int)s2.length());
  25. }
  26. int a[10] = { 0,3,1,4,7,9,20,8,10,15 };
  27. string b[6] = { "American","Jack","To","Peking","abcdefghijklmnop","123456789" };
  28. int main()
  29. {
  30. int n; string s;
  31. while (cin >> n >> s) {
  32. sort(a, a + 10, Closer<int, int (*)(int, int)>(n, Distance1));
  33. for (int i = 0; i < 10; ++i)
  34. cout << a[i] << ",";
  35. cout << endl;
  36. sort(b, b + 6, Closer<string, int (*)(const string&, const string&)>(s, Distance2));
  37. for (int i = 0; i < 6; ++i)
  38. cout << b[i] << ",";
  39. cout << endl;
  40. }
  41. return 0;
  42. }

006:我自己的 ostream_iterator

总时间限制: 

1000ms

 

内存限制: 

65536kB

// 在此处补充你的代码

描述

程序填空输出指定结果

#include <iostream>
#include <list>
#include <string>
using namespace std;

template <class T1,class T2>
void Copy(T1 s,T1 e, T2 x)
{
	for(; s != e; ++s,++x)
		*x = *s;
}

 
template<class T>
class myostream_iteraotr
{
};


int main()
{	const int SIZE = 5;
	int a[SIZE] = {5,21,14,2,3};
	double b[SIZE] = { 1.4, 5.56,3.2,98.3,3.3};
	list<int> lst(a,a+SIZE);
	myostream_iteraotr<int> output(cout,",");
	Copy( lst.begin(),lst.end(),output); 
	cout << endl;
	myostream_iteraotr<double> output2(cout,"--");
	Copy(b,b+SIZE,output2);
	return 0;
}

输入

输出

5,21,14,2,3,
1.4--5.56--3.2--98.3--3.3--

样例输入

样例输出

同输入

来源

Guo Wei

这个题目有点难,需要传入的是一个对象,其中实现了* ++ =运算的重载操作。

  1. #include <iostream>
  2. #include <list>
  3. #include <string>
  4. using namespace std;
  5. template <class T1, class T2>
  6. void Copy(T1 s, T1 e, T2 x)
  7. {
  8. for (; s != e; ++s, ++x)
  9. * x = *s;
  10. }
  11. template<class T>
  12. class myostream_iteraotr
  13. {
  14. T x;
  15. string str;
  16. // 在此处补充你的代码
  17. ostream& os;
  18. public:
  19. myostream_iteraotr(ostream& os_, string s):os(os_),str(s){}
  20. void operator++ (){}
  21. myostream_iteraotr& operator * () { return *this; }
  22. myostream_iteraotr& operator =(const T& t)
  23. {
  24. os << t << str;
  25. return *this;
  26. }
  27. };
  28. int main()
  29. {
  30. const int SIZE = 5;
  31. int a[SIZE] = { 5,21,14,2,3 };
  32. double b[SIZE] = { 1.4, 5.56,3.2,98.3,3.3 };
  33. list<int> lst(a, a + SIZE);
  34. myostream_iteraotr<int> output(cout, ",");
  35. Copy(lst.begin(), lst.end(), output);
  36. cout << endl;
  37. myostream_iteraotr<double> output2(cout, "--");
  38. Copy(b, b + SIZE, output2);
  39. return 0;
  40. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/208350
推荐阅读
相关标签
  

闽ICP备14008679号