【程序设计实习】第七次上机复盘

01:编程填空:字符串排序

描述

请按照要求对输入的字符串进行排序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <string>
#include <list>
using namespace std;

class A{
private:
	string name;
public:
	A(string n) :name(n){}
	friend bool operator < (const class A& a1, const class A &a2);
	friend bool operator == (const class A &a1, const class A &a2){
		if (a1.name.size() == a2.name.size())
			return true;
		else
			return false;
	}
	friend ostream & operator << (ostream &o, const A &a){
		o << a.name;
		return o;
	}
	string get_name() const{
		return name;
	}
	int get_size() const{
		return name.size();
	}
};
// 在此处补充你的代码
int main(int argc, char* argv[])
{
	list<A> lst;
	int ncase, n, i = 1;
	string s;
	cin >> ncase;
	while (ncase--){
		cout << "Case: "<<i++ << endl;
		cin >> n;
		for (int i = 0; i < n; i++){
			cin >> s;
			lst.push_back(A(s));
		}
		lst.sort();
		Show(lst.begin(), lst.end(), Print());

		cout << endl;
		lst.sort(MyLarge<A>());
		Show(lst.begin(), lst.end(), Print());
		cout << endl;
		lst.clear();

	}
	return 0;
}

输入

第一行是正整数T,表示测试数据的组数
每组测试数据输入共两行,
第一行是正整数N,表示字符串个数
第二行是N个字符串, 字符串间用空格分离

输出

对于每组测试数据,先输出一行:
Case: n 如对第一组数据就输出Case: 1
第二行按照字符串长度从小到大排序之后输出N个字符串,字符串之间以空格间隔(不会出现字符串长度相同的情况)
第三行按照字符串首字符ASCII码序从小到大排序之后输出N个字符串,字符串之间以空格间隔(不会出现字符串首字母相同的情况)

样例输入

1
2
3
4
5
2
4
a bnss ds tsdfasg
5
aaa bbbb ccccd sa q

样例输出

1
2
3
4
5
6
Case: 1
a ds bnss tsdfasg
a bnss ds tsdfasg 
Case: 2
q sa aaa bbbb ccccd
aaa bbbb ccccd q sa

Solution

这里我们可以看到,题目中给了我们get_name和get_size两个函数,那就把它用起来吧
同时从友元看出,需要我们重载<这个运算符
同时,需要写出一个MyLarge的模板类
然后,还需要写出show和print两个函数
最大意的地方在于之前忘记模板类的对象可以通过重载()运算符来仿函数,所以卡了一会
下面看代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <string>
#include <list>
using namespace std;

class A{
private:
	string name;
public:
	A(string n) :name(n){}
	friend bool operator < (const class A& a1, const class A &a2);
	friend bool operator == (const class A &a1, const class A &a2){
		if (a1.name.size() == a2.name.size())
			return true;
		else
			return false;
	}
	friend ostream & operator << (ostream &o, const A &a){
		o << a.name;
		return o;
	}
	string get_name() const{
		return name;
	}
	int get_size() const{
		return name.size();
	}
};
bool operator<(const class A& a1,const class A& a2){
    return a1.get_size()<a2.get_size();
}
template<class T>
struct MyLarge{
    bool operator()(const T& a1,const T& a2){
        return a1.get_name()<a2.get_name();
    }
};
template<class T1,class T2>
void Show(T1 x,T1 y,T2 f){
    for(auto it=x;it!=y;it++){
        f(*it);
    }
}
struct Print{
    void operator()(const A& a)const{
        cout<<a.get_name()<<' ';
    }
};
int main(int argc, char* argv[])
{
	list<A> lst;
	int ncase, n, i = 1;
	string s;
	cin >> ncase;
	while (ncase--){
		cout << "Case: "<<i++ << endl;
		cin >> n;
		for (int i = 0; i < n; i++){
			cin >> s;
			lst.push_back(A(s));
		}
		lst.sort();
		Show(lst.begin(), lst.end(), Print());

		cout << endl;
		lst.sort(MyLarge<A>());
		Show(lst.begin(), lst.end(), Print());
		cout << endl;
		lst.clear();

	}
	return 0;
}

02:按距离排序

描述

程序填空,输出指定结果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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的距离从小到大输出。距离相同的,字典序小的排在前面

样例输入

1
2
2 a123456
4 a12345

样例输出

1
2
3
4
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,

Solution

我们确实大意了,函数可以作为模板类的一个对象,如果知道了就好说了,直接重载()即可
下面看代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
template <class T1,class T2>
struct Closer {
T1 z;
    T2 f;
    Closer(T1 a,T2 b):z(a),f(b) { }
    bool operator()(T1 x,T1 y){
        if(f(x,z)==f(y,z)) return x<y;
        return f(x,z)<f(y,z);
    }
};

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

03:回调函数

描述

输入x1 x2 x3 x4 x5 ,输出y = x5^5 + x4^4 + x3^3 + x2^2 + x1^1 + 1的y的值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <map>
#include <set>

using namespace std;
class MyFunc
{
// 在此处补充你的代码
};
int main()
{
	int n;
	cin >> n;
	while(n--) {
		vector<MyFunc> v;
		for (int i = 0; i < 5; ++i)
			v.push_back(MyFunc(i+1));
		int ans = 1;
		for (int i = 0; i < 5; ++i)
		{
			int m;
			cin >> m;
			ans += v[i](m);
		}
		cout << ans <<endl;
	}
}

输入

多组数据。第一行是数据组数 n
每组数据为一行,5个整数,x1 x2 x3 x4 x5。数值不大,不必考虑溢出

输出

对每组数据,输出一个整数y, y = x5^5 + x4^4 + x3^3 + x2^2 + x1^1 + 1

样例输入

1
2
3
2
2 2 2 2 2
1 1 1 1 1

样例输出

1
2
63
6

Solution

这道题就是要求我们重载出一个仿函数,然后这个仿函数作为一个类对象被加入vector中然后狗作用于m,所以,我们只需要重载一个()即可
下面看代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <map>
#include <set>

using namespace std;
class MyFunc
{
int p;
public:
    MyFunc(int x):p(x) { }
    int operator()(int x){
        return pow(x,p);
    }
};
int main()
{
	int n;
	cin >> n;
	while(n--) {
		vector<MyFunc> v;
		for (int i = 0; i < 5; ++i)
			v.push_back(MyFunc(i+1));
		int ans = 1;
		for (int i = 0; i < 5; ++i)
		{
			int m;
			cin >> m;
			ans += v[i](m);
		}
		cout << ans <<endl;
	}
}

04:编程填空:Printer

描述

完成以下程序,使得输入的整数x,以及若干正整数,将大于x的正整数输出;
然后输入若干字符串,将字符串长度大于x的字符串输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<algorithm>
#include<vector>
#include<bitset>

using namespace std;


class Printer{
// 在此处补充你的代码
int main(){

	int t;
	cin >> t;
	while(t--) {
		int n,x;
		cin>>x>>n;
		
		vector<int> intVec;
		for(int i = 0;i < n; ++i) {
			int y;
			cin >> y;
			intVec.push_back(y);
		}
		for_each(intVec.begin(), intVec.end(), Printer(x));
		cout<<endl;
		
		vector<string> strVec;
		for(int i = 0;i < n; ++i) {
			string str;
			cin >> str;
			strVec.push_back(str);
		}
		for_each(strVec.begin(), strVec.end(), Printer(x));
		cout<<endl;
	}
	return 0;
}

输入

第一行是整数t,表示一共t组数据
每组数据有三行
第一行是整数x和整数 n
第二行是n个整数
第三行是n个不带空格的字符串

输出

对每组数据
先按原序输出第一行中大于x的正整数(数据保证会有输出)
再按原序输出第二行中长度大于x的字符串 (数据保证会有输出)

样例输入

1
2
3
4
5
6
7
2
5 6
1 3 59 30 2 40
this is hello please me ha
1 1
4
this

样例输出

1
2
3
4
59,30,40,
please,
4,
this,

Solution

本题没有为我们准备模板类
而且对于string和int两个类的判断函数是不一样的
所以,我们需要重载两次

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<iostream>
#include<algorithm>
#include<vector>
#include<bitset>

using namespace std;


class Printer{
private:
    int p;
public:
    Printer(int x):p(x) { }
    void operator()(int x){
        if(x>p) cout<<x<<',';
    }
    void operator()(string x){
        if(x.length()>p) cout<<x<<','; 
    }
};
int main(){

	int t;
	cin >> t;
	while(t--) {
		int n,x;
		cin>>x>>n;
		
		vector<int> intVec;
		for(int i = 0;i < n; ++i) {
			int y;
			cin >> y;
			intVec.push_back(y);
		}
		for_each(intVec.begin(), intVec.end(), Printer(x));
		cout<<endl;
		
		vector<string> strVec;
		for(int i = 0;i < n; ++i) {
			string str;
			cin >> str;
			strVec.push_back(str);
		}
		for_each(strVec.begin(), strVec.end(), Printer(x));
		cout<<endl;
	}
	return 0;
}

05:矩阵排序

描述

创建矩阵类,要求能够输入整数类型的m*n矩阵,并按照元素个数,矩阵中元素之和,创建矩阵顺序对矩阵类分别排序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Mat{
	int h,w;
public:
	Mat(int height,int width):h(height),w(width)
// 在此处补充你的代码
int main()
{
	vector<Mat> m;
	m.push_back(Mat(2,2));
	m.push_back(Mat(3,4));
	m.push_back(Mat(2,2));
	cin >> m[0] >> m[1] >> m[2];
	sort(m.begin(),m.end());
	cout<< m[0] << endl << m[1] << endl << m[2] <<endl;
	cout<<"*************"<<endl;
	sort(m.begin(),m.end(),comparator_1);
	cout<< m[0] << endl << m[1] << endl << m[2] <<endl;
	cout<<"*************"<<endl;
	sort(m.begin(),m.end(),comparator_2());
	cout<< m[0] << endl << m[1] << endl << m[2] <<endl;
	return 0;
}

输入

前两行是一个22矩阵
之后三行是一个3
4矩阵
最后两行是一个2*2矩阵

输出

先按照元素个数从小到大输出三个矩阵(大小相同时后创建的矩阵先输出)
再按照元素之和从小到大输出三个矩阵(大小相同时后创建的矩阵先输出)
再按照矩阵创建顺序从先到后输出三个矩阵
(矩阵排列方式与输入相同,每个元素后用一个空格进行分隔)

样例输入

1
2
3
4
5
6
7
2 3
3 4
 0 12 -3 -4
-2  2 -1  0
-1 -1 -1 -1
-1 3
-2 4

样例输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-1 3
-2 4

2 3
3 4

0 12 -3 -4
-2 2 -1 0
-1 -1 -1 -1

*************
0 12 -3 -4
-2 2 -1 0
-1 -1 -1 -1

-1 3
-2 4

2 3
3 4

*************
2 3
3 4

0 12 -3 -4
-2 2 -1 0
-1 -1 -1 -1

-1 3
-2 4

Solution

其实是简单的矩阵题,然后重载输入输出和一个判断函数和一个模板判断函数,最后,输入顺序我们用一个静态成员变量表示,就可以了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Mat{
	int h,w;
public:
	Mat(int height,int width):h(height),w(width)
{
        p=new int[h*w];
        k++;
        id=k;
        tot=h*w;
        sum=0;
    }
    int* p;
    int id;
    int sum;
    int tot;
    static int k;
    bool operator<(const Mat &x){
        if(tot==x.tot) return id>x.id;
        return tot<x.tot;
    }
    friend istream &operator>>(istream &is,Mat x){
        for(int i=0;i<=x.h-1;i++){
            for(int j=0;j<=x.w-1;j++){
                is>>x.p[i*x.w+j];
            }
        } 
        for(int i=0;i<x.h*x.w;i++) x.sum+=x.p[i];
        return is;
    }
    friend ostream &operator<<(ostream &os,Mat x){
        for(int i=0;i<=x.h-1;i++){
            for(int j=0;j<=x.w-1;j++){
                os<<x.p[i*x.w+j]<<' ';
            }
            os<<endl;
        }
        return os;
    }
};
int Mat::k=0;
bool comparator_1(Mat x,Mat y){
    for(int i=0;i<x.tot;i++) x.sum+=x.p[i];
    for(int i=0;i<y.tot;i++) y.sum+=y.p[i];
    if(x.sum==y.sum) return x.id>y.id;
    return x.sum<y.sum;
}
struct comparator_2{
    bool operator()(Mat x,Mat y){
        return x.id<y.id;
    }
};
int main()
{
	vector<Mat> m;
	m.push_back(Mat(2,2));
	m.push_back(Mat(3,4));
	m.push_back(Mat(2,2));
	cin >> m[0] >> m[1] >> m[2];
	sort(m.begin(),m.end());
	cout<< m[0] << endl << m[1] << endl << m[2] <<endl;
	cout<<"*************"<<endl;
	sort(m.begin(),m.end(),comparator_1);
	cout<< m[0] << endl << m[1] << endl << m[2] <<endl;
	cout<<"*************"<<endl;
	sort(m.begin(),m.end(),comparator_2());
	cout<< m[0] << endl << m[1] << endl << m[2] <<endl;
	return 0;
}

06:编程填空:数组输出

描述

填写代码,创建Print模板类,要求对输入的字符串数组或整数数组,用模板类进行输出并自动换行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;
// 在此处补充你的代码
int main(){
	string s[20];
	int num[20];
	int m,n;
	
	while(cin >> m >> n){
		for(int i=0; i<m; i++){
			cin >> s[i];
		}
		accumulate(s, s+m, Print<string>(m));
		for(int i=0; i<n; i++){
			cin >> num[i];
		}
		accumulate(num, num+n, Print<int>(n));
	}
}

输入

有多个输入样例
每个样例的第一行为两个整数m,n(m,n不超过20)
每个样例的第二行为m个字符串
每个样例的第三行为n个整数

输出

对每个样例输出两行
第一行为输入的字符串(去除空格)
第二行为输入的整数(去除空格)

样例输入

1
2
3
4
5
6
3 3
abc def hij
12 34 56
2 5
Peking University
20 18 05 1 3

样例输出

1
2
3
4
abcdefhij
123456
PekingUniversity
2018513

Solution

这里我们介绍一个新知识点,叫做链式加法
这是什么?
就是说,我们对于一个加法,返回的是原来的仿函数模板类对象
这样就完了
而且题目给了我们输出次数,完全可以做出链式的断裂条件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;
template<class T>
class Print{
    int x;
public:
    Print(int a):x(a) { }
    Print<T>& operator+(T d){
        x--;
        cout<<d;
        if(x==0) cout<<endl;
        return *this;
    } 
};
int main(){
	string s[20];
	int num[20];
	int m,n;
	
	while(cin >> m >> n){
		for(int i=0; i<m; i++){
			cin >> s[i];
		}
		accumulate(s, s+m, Print<string>(m));
		for(int i=0; i<n; i++){
			cin >> num[i];
		}
		accumulate(num, num+n, Print<int>(n));
	}
}

07:编程填空:正向与反向输出

描述

输入一个的序列,首先输出原序列,每个元素之间以"—“分开
再将序列的每个元素翻倍,并逆序输出原序列,每个元素之间以”***“分开。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
class C1{
// 在此处补充你的代码
};

int main()
{
    vector<int> v;
    int p;
    int size;
    int k;
    cin >> k;
    while(k--){
        cin >> size;
        v.clear();
        for(int i = 0; i < size; ++i){
            cin >> p;
            v.push_back(p);
        }
        C1 o1 = C1(size,v);
        ostream_iterator<int> it(cout,"---");
        copy(*o1, (*o1)+size, it);
        cout<<endl;
        for(int i = 0; i < size; ++i){
            o1[i]*=2;
            cout<<o1[i]<<"***";
        }
        cout<<endl;
    }    
}

输入

第一行是测试数据组数k。
对于每组测试数据,先输入
测试数据共有k组,每组首先输入序列长度n,接下来n个整数分别代表序列的n个数。

输出

对于每组测试数据输出两行,分别是以”—“分割的原序列,和以”***“分割的翻倍后的逆序序列。

样例输入

1
2
3
1
10
1 2 3 4 5 6 7 8 9 10

样例输出

1
2
1---2---3---4---5---6---7---8---9---10---
20***18***16***14***12***10***8***6***4***2***

Solution

仔细阅读ppt中关于copy的定义即可轻松得出答案~

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
class C1{
private:
    int siz;
    vector<int> k;
public:
    C1(int x,vector<int> t):siz(x),k(t) { }
    C1(C1 &b){
        siz=b.siz;
        k=b.k;
    }
    vector<int>::iterator operator*(){
        return k.begin();
    }
    int& operator[](int x){
        return k[siz-x-1];
    }
    void operator*=(int& k){
        k*=2;
        return ;
    }
};

int main()
{
    vector<int> v;
    int p;
    int size;
    int k;
    cin >> k;
    while(k--){
        cin >> size;
        v.clear();
        for(int i = 0; i < size; ++i){
            cin >> p;
            v.push_back(p);
        }
        C1 o1 = C1(size,v);
        ostream_iterator<int> it(cout,"---");
        copy(*o1, (*o1)+size, it);
        cout<<endl;
        for(int i = 0; i < size; ++i){
            o1[i]*=2;
            cout<<o1[i]<<"***";
        }
        cout<<endl;
    }
}

08:找第一个最小的

描述

写出 FindFirstLess 模板,用于寻找序列中小于某指定值的第一个元素

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 在此处补充你的代码
int main()
{
	int t;
	cin >> t;
	while(t--) {
		int n ;
		string type; 
		cin >> n >> type;
		vector<int> vi;
		vector<string> vs;
		if( type == "N") {
			int a,m;
			for(int i = 0;i < n  - 1; ++i) {
				
				cin >> a;
				vi.push_back(a);
			}
			cin >> m;
			vector<int>::iterator p = FindFirstLess(vi.begin(),vi.end(),m,less<int>());
			if( p!= vi.end())
				cout << * p << endl;
			else
				cout << "Not Found" << endl; 
				
		}
		else {
			string a,m;
			for(int i = 0;i < n - 1; ++i) {
				cin >> a;
				vs.push_back(a);
			}
			cin >> m;
			vector<string>::iterator p = FindFirstLess(vs.begin(),vs.end(),m,less<string>());
			if( p!= vs.end())
				cout << * p << endl;
			else
				cout << "Not Found" << endl; 
		
		}
	}
    return 0;
}

输入

第一行是测试数据组数T
接下来有2T行,每两行是一组测试数据
每组数据第一行开始是一个整数,表示这组数据有n项;接下来是一个字母,如果是’N’,表示这组数据都是整数,如果是’S’表示这组数据都是字符串
第二行就是n个整数,或者n个字符串

输出

对每组数据,输出第二行的前n-1项里面,第一个小于第n项的 。如果找不到,输出 “Not Found”

样例输入

1
2
3
4
5
6
7
3
4 N
28 12 7 15
4 S
Jack Tom Marry Ken
4 N
100 200 300 2

样例输出

1
2
3
12
Jack
Not Found

Solution

其实这道题就是普通的函数模板
我们可以看到less返回了一个实例化的函数模板类
那么,我们直接写一个函数就可以了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<class T1,class T2,class T3>
T1 FindFirstLess(T1 x,T1 y,T2 t,T3 f){
    bool flag=false;
    T1 k;
    for(T1 it=x;it!=y;it++){
        if(*it<t){
            flag=1;
            k=it;
            break;
        }
    }
    if(flag) return k;
    else return y;
}
int main()
{
	int t;
	cin >> t;
	while(t--) {
		int n ;
		string type; 
		cin >> n >> type;
		vector<int> vi;
		vector<string> vs;
		if( type == "N") {
			int a,m;
			for(int i = 0;i < n  - 1; ++i) {
				
				cin >> a;
				vi.push_back(a);
			}
			cin >> m;
			vector<int>::iterator p = FindFirstLess(vi.begin(),vi.end(),m,less<int>());
			if( p!= vi.end())
				cout << * p << endl;
			else
				cout << "Not Found" << endl; 
				
		}
		else {
			string a,m;
			for(int i = 0;i < n - 1; ++i) {
				cin >> a;
				vs.push_back(a);
			}
			cin >> m;
			vector<string>::iterator p = FindFirstLess(vs.begin(),vs.end(),m,less<string>());
			if( p!= vs.end())
				cout << * p << endl;
			else
				cout << "Not Found" << endl; 
		
		}
	}
    return 0;
}

09:输出Fibonacci数列

描述

Fibonacci数列指的是数列第一项和第二项为1,之后每一项是之前两项的和所构成的数列。 现有多组数据,每组数据给出一个数字n,请你输出Fibonacci数列的前n-1项。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <iterator>
using namespace std;

template<class T1, class T2>
void Copy(T1 s, T1 e, T2 x) {
    for(; s != e; ++s, ++x)
        *x = *s;
}
// 在此处补充你的代码
int main() {
	while(true) {
		int n;
		cin >> n;
		if(n == 0)
			break;
		
	    Fib f1(1), f2(n);
	    ostream_iterator<int> it(cout, " ");
	    Copy(f1, f2, it);
	    cout << endl;
	}
	return 0;
}

输入

每组数据一行,整数n 输入以0结尾

输出

对每组数据输出前 n-1项

样例输入

1
2
3
0

样例输出

1
1 1

Solution

这道题我其实看不大懂,然后查了一下发现每个类里需要存一下现在的值和上一个函数的值,重载++和!=的时候跟已经得到的值进行比较,然后*就是重载成输出,就可以了

  • 笔者注:学了python的面向对象编程和生成器后更有感觉了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <iterator>
using namespace std;

template<class T1, class T2>
void Copy(T1 s, T1 e, T2 x) {
    for(; s != e; ++s, ++x)
        *x = *s;
}
class Fib{
    int num;
    int pre;
    int tem;
public:
    Fib(int n):num(n),pre(0),tem(1) { }
    void operator++(){
        num++;
        int cur=tem;
        cur=tem+pre;
        pre=tem;
        tem=cur;
    }
    bool operator!=(const Fib &s){
        return num!=s.num;
    }
    int operator*(){
        return tem;
    }
};
int main() {
	while(true) {
		int n;
		cin >> n;
		if(n == 0)
			break;
		
	    Fib f1(1), f2(n);
	    ostream_iterator<int> it(cout, " ");
	    Copy(f1, f2, it);
	    cout << endl;
	}
	return 0;
}

10:改良过的CArray3d三维数组模板类

描述

程序填空,按要求输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
template <class T>
class CArray3D
{
// 在此处补充你的代码
};

CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{
    for(int i = 0;i < 3; ++i) {
        cout << "layer " << i << ":" << endl;
        for(int j = 0; j < 4; ++j) {
            for(int k = 0; k < 5; ++k)
                cout << a[i][j][k] << "," ;
            cout << endl;
        }
    }
}
void PrintB()
{
    for(int i = 0;i < 3; ++i) {
        cout << "layer " << i << ":" << endl;
        for(int j = 0; j < 2; ++j) {
            for(int k = 0; k < 2; ++k)
                cout << b[i][j][k] << "," ;
            cout << endl;
        }
    }
}

int main()
{
    
    int No = 0;
    for( int i = 0; i < 3; ++ i )
        for( int j = 0; j < 4; ++j )
            for( int k = 0; k < 5; ++k )
                a[i][j][k] = No ++;
    PrintA();
    memset(a, -1, 60 * sizeof(int));        //注意这里
    memset(a[1][1], 0, 5 * sizeof(int));
    PrintA();
    
    for( int i = 0; i < 3; ++ i )
        for( int j = 0; j < 2; ++j )
            for( int k = 0; k < 2; ++k )
                b[i][j][k] = 10.0 / (i + j + k + 1);
    PrintB();
    int n = a[0][1][2];
    double f = b[0][1][1];
    cout << "****" << endl;
    cout << n << "," << f << endl;
    
    return 0;
}

输入

输出

如样例

样例输入

1

样例输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
20,21,22,23,24,
25,26,27,28,29,
30,31,32,33,34,
35,36,37,38,39,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 1:
-1,-1,-1,-1,-1,
0,0,0,0,0,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 0:
10,5,
5,3.33333,
layer 1:
5,3.33333,
3.33333,2.5,
layer 2:
3.33333,2.5,
2.5,2,
****
-1,3.33333

Solution

说是改良了,其实没有
用上次的代码完全能过,不解释

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
template <class T>
class CArray3D
{
private:
    int x,y,z;
    T* p;
public:
    CArray3D(int a,int b,int c):x(a),y(b),z(c) { 
        p=new T[x*y*z];
    }
    class CArray2D{
    private:
        int y,z;
        T* dd;
    public:
        CArray2D(T* d,int b,int c):dd(d),y(b),z(c) { }
        T* operator[](int index){
            T* t=dd+index*z;
            return t;
        }
    };
    CArray2D operator[](int index){
        T* dd=p+index*y*z;
        return CArray2D(dd,y,z);
    }
    operator T*(){
        return p;
    }
};

CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{
    for(int i = 0;i < 3; ++i) {
        cout << "layer " << i << ":" << endl;
        for(int j = 0; j < 4; ++j) {
            for(int k = 0; k < 5; ++k)
                cout << a[i][j][k] << "," ;
            cout << endl;
        }
    }
}
void PrintB()
{
    for(int i = 0;i < 3; ++i) {
        cout << "layer " << i << ":" << endl;
        for(int j = 0; j < 2; ++j) {
            for(int k = 0; k < 2; ++k)
                cout << b[i][j][k] << "," ;
            cout << endl;
        }
    }
}

int main()
{
    
    int No = 0;
    for( int i = 0; i < 3; ++ i )
        for( int j = 0; j < 4; ++j )
            for( int k = 0; k < 5; ++k )
                a[i][j][k] = No ++;
    PrintA();
    memset(a, -1, 60 * sizeof(int));        //注意这里
    memset(a[1][1], 0, 5 * sizeof(int));
    PrintA();
    
    for( int i = 0; i < 3; ++ i )
        for( int j = 0; j < 2; ++j )
            for( int k = 0; k < 2; ++k )
                b[i][j][k] = 10.0 / (i + j + k + 1);
    PrintB();
    int n = a[0][1][2];
    double f = b[0][1][1];
    cout << "****" << endl;
    cout << n << "," << f << endl;
    
    return 0;
}
本博客已稳定运行
发表了27篇文章 · 总计103.29k字
使用 Hugo 构建
主题 StackJimmy 设计