A:高阶函数F(x)
描述
lisp语言中有高阶函数的概念,即函数可以作为函数的参数,也可以作为函数的返回值。例如:
(define (f n) (lambda (x) (+ x n)))
定义了一个函数f,该函数的返回值是另一个函数,假定称为g即 (lambda (x) (+ x n) 此函数功能是参数为x,返回值为x + n。 于是 ((f 7) 9) 如下执行
(f 7)以参数7调用f, f的返回值是g,n的值为7
((f 7) 9)等价于 (g 9),即以参数9调用g。 因 n = 7, x = 9 ,因此(g 9)返回值为16
编写一个C++的通用函数模板f,使之能完成类似于lisp函数f的功能。 对于下面的程序,输出结果是
16
world hello!
world!
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <iostream>
using namespace std;
// 在此处补充你的代码
int main()
{
cout << f<int,int>(7)(9) << endl; //16
cout << f<string,string> (" hello!")("world") <<endl; // world hello!
cout << f<char,string> ('!')("world") << endl;
return 0; //world!
}
|
输入
无
输出
16
world hello!
world!
样例输入
样例输出
1
2
3
|
16
world hello!
world!
|
提示
C++函数模板实例化时,也可以通过在<>中指定类型参数所对应的具体类型来实现。
Solution
其实不要管题目给的背景,知道是后面的加前面的,然后直接用仿函数重载()即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <iostream>
using namespace std;
template<class T1,class T2>
class f{
private:
T1 x;
public:
f(T1 k):x(k) { }
T2 operator()(T2 k){
return k+x;
}
};
int main()
{
cout << f<int,int>(7)(9) << endl; //16
cout << f<string,string> (" hello!")("world") <<endl; // world hello!
cout << f<char,string> ('!')("world") << endl;
return 0; //world!
}
|
B:高阶函数Combine
描述
Lisp语言中有高阶函数的概念,即函数可以作为函数的参数,也可以作为函数的返回值。例如:
(define (square x) (* xx)) 定义了一个求x的平方的函数
(define (inc x) (+ x1)) 定义了一个求x+1的函数
(define (combine f g) (lambda (x) (f (+ (fx) (g x)))))
(combine f g) 返回函数k , k(x) = f( f(x)+g(x))
因此 ((combine square inc) 3) 的返回值就是169
此处
f(x) = x*x g(x) = x + 1
k(x) = (x*x+(x+1)) ^2
((combine square inc) 3) 即是 k(3)
因此返回值为169 用C++实现类似的combine函数模板,使得下面的程序输出结果为
169
10.75
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <iostream>
using namespace std;
// 在此处补充你的代码
int main()
{
auto Square = [] (double a) { return a * a; };
auto Inc = [] (double a) { return a + 1; };
cout << combine<decltype(Square),decltype(Inc),int>(Square,Inc)(3) << endl;
cout << combine<decltype(Inc),decltype(Square),double>(Inc,Square)(2.5) << endl;
return 0;
}
|
输入
无
输出
169
10.75
样例输入
样例输出
提示
C++函数模板实例化时,也可以通过在<>中指定类型参数所对应的具体类型来实现。
Solition
这题跟C++11有关的也就是auto,显而易见的lambda函数和一个需要一点感觉的仿函数模板?
哦还有这个,decltype的几个规则,总之知道它这里返回的就是函数指针,指向某个lambda函数
然后,这个Combine类有三个变量类型,完了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <iostream>
using namespace std;
template<class T1,class T2,class T3>
class combine{
private:
T1 a;
T2 b;
public:
combine(T1 x,T2 y):a(x),b(y) { }
T3 operator()(T3 x){
return a(a(x)+b(x));
}
};
int main()
{
auto Square = [] (double a) { return a * a; };
auto Inc = [] (double a) { return a + 1; };
cout << combine<decltype(Square),decltype(Inc),int>(Square,Inc)(3) << endl;
cout << combine<decltype(Inc),decltype(Square),double>(Inc,Square)(2.5) << endl;
return 0;
}
|
C:自己实现bitset
描述
程序填空,实现一个类似STL bitset的 MyBitset, 输出指定结果
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 <cstring>
using namespace std;
template <int bitNum>
struct MyBitset
{
char a[bitNum/8+1];
MyBitset() { memset(a,0,sizeof(a));};
void Set(int i,int v) {
char & c = a[i/8];
int bp = i % 8;
if( v )
c |= (1 << bp);
else
c &= ~(1 << bp);
}
// 在此处补充你的代码
void Print() {
for(int i = 0;i < bitNum; ++i)
cout << (*this) [i];
cout << endl;
}
};
int main()
{
int n;
int i,j,k,v;
while( cin >> n) {
MyBitset<20> bs;
for(int i = 0;i < n; ++i) {
int t;
cin >> t;
bs.Set(t,1);
}
bs.Print();
cin >> i >> j >> k >> v;
bs[k] = v;
bs[i] = bs[j] = bs[k];
bs.Print();
cin >> i >> j >> k >> v;
bs[k] = v;
(bs[i] = bs[j]) = bs[k];
bs.Print();
}
return 0;
}
|
输入
多组数据
每组数据:
第一行是整数 n , 1 <= n < 20;
第二行是n个整数 k1,k2… kn,均在范围 [0,19]内。
第三行是 四个整数 i1,j1,k1,v1 。 0 <= i1,j1,k1 <= 19, v1值为0或1
第三行是 四个整数 i2,j2,k2,v2 。 0 <= i2,j2,k2 <= 19, v2值为0或1
输出
对每组数据,共输出3行,每行20位,每位为1或者0。最左边称为第0位
第一行: 第 k1,k2 … kn位为1,其余位为0。
第二行: 将第一行中的第 i1,j1,k1位变为 v1,其余位不变
第三行: 将第二行中的第i2位和k2位变为v2,其余位不变
样例输入
1
2
3
4
5
6
7
8
|
4
0 1 2 8
7 19 0 1
7 2 8 0
1
1
1 1 1 0
1 1 1 1
|
样例输出
1
2
3
4
5
6
|
11100000100000000000
11100001100000000001
11100000000000000001
01000000000000000000
00000000000000000000
01000000000000000000
|
提示
推荐使用内部类,内部类中使用引用成员。引用成员要在构造函数中初始化。
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
|
#include <iostream>
#include <cstring>
using namespace std;
template <int bitNum>
struct MyBitset
{
char a[bitNum/8+1];
MyBitset() { memset(a,0,sizeof(a));};
void Set(int i,int v) {
char & c = a[i/8];
int bp = i % 8;
if( v )
c |= (1 << bp);
else
c &= ~(1 << bp);
}
int myb[20];
bool flag=false;
void transform(){
memset(myb,0,sizeof(myb));
for(int i=0;i<=bitNum/8+1;i++){
int temp=i*8;
int num=(unsigned char)(a[i]);
while(num>0){
if(num%2) myb[temp]++;
temp++;
num/=2;
}
}
flag=true;
}
int &operator[](int x){
if(!flag) transform();
return myb[x];
}
void Print() {
for(int i = 0;i < bitNum; ++i)
cout << (*this) [i];
cout << endl;
}
};
int main()
{
int n;
int i,j,k,v;
while( cin >> n) {
MyBitset<20> bs;
for(int i = 0;i < n; ++i) {
int t;
cin >> t;
bs.Set(t,1);
}
bs.Print();
cin >> i >> j >> k >> v;
bs[k] = v;
bs[i] = bs[j] = bs[k];
bs.Print();
cin >> i >> j >> k >> v;
bs[k] = v;
(bs[i] = bs[j]) = bs[k];
bs.Print();
}
return 0;
}
|