CPP2022-23-函数进阶-函数指针

6-1 函数指针(理科实验班)

分数 20

全屏浏览题目

切换布局

作者 何振峰

单位 福州大学

梦山高中现需要将某普通班的最优秀学生调整入理科实验班。为此,将从两个方面考察学生,一是数学和英语两门课的总分;另一个是所有四门课的总分。分别找出两科总分和全科总分的第一名,并从中决定调整人选。

输入将首先输入学生数n, (n为不超过80的正整数);接下来依次输入各位学生的学号,数学、英语、语文、理科综合成绩。学号及四科成绩均为不超过300的正整数。

输出时:第一行输出两科总分第一的学号,第二行输出四科总分第一的学号。 约定在两位学生成绩相同时,优先选择学号较小的学生;各位学生的学号均不相同。

裁判测试程序样例:

 

#include <iostream> using namespace std; const int N=80; struct Student{ int num; int score[4]; }; /* 请在这里填写答案 */ int main() { int i, j, k, n; bool s2(const Student &, const Student &); bool s4(const Student &, const Student &); Student st[N]; cin>>n; for(i=0;i<n;i++){ cin>>st[i].num; for(j=0;j<4;j++) cin>>st[i].score[j]; } cout<<select(st, n, s2)<<endl; cout<<select(st, n, s4)<<endl; }

输入样例:

3
6 148 150 120 252
5 148 150 117 260
7 145 148 128 287

输出样例:

5
7
bool s2(const Student &a, const Student &b)
{
    if(a.score[0]+a.score[1]!=b.score[0]+b.score[1])
    {
        return a.score[0]+a.score[1]>b.score[0]+b.score[1];
    }
    else
    {
        return a.num<b.num;
    }
}
bool s4(const Student &a, const Student &b)
{
    if(a.score[0]+a.score[1]+a.score[2]+a.score[3]!=b.score[0]+b.score[1]+b.score[2]+b.score[3])
    {
        return a.score[0]+a.score[1]+a.score[2]+a.score[3]>b.score[0]+b.score[1]+b.score[2]+b.score[3];
    }
    else
    {
        return a.num<b.num;
    }
}
int select(Student st[],int n,bool(*s)(const Student &a,const Student &b))
{
    int max=0;
    for(int i=1;i<n;i++)
    {
        if(!s(st[max],st[i]))
        {
            max=i;
        }
    }
    return st[max].num;
}

6-2 玩转函数指针

分数 20

全屏浏览题目

切换布局

作者 周强

单位 青岛大学

这道题,让我们来玩转函数指针。

函数接口定义:

 

void proceed(int *a, int *b, int size, void (*fp)(int x, int y));

其中,参数ab是分别是两个相同大小的整型数组的首地址,size是两个数组的长度,fp是一个函数指针。

题目要求,proceed函数依次以数组ab里的每一对元素为参数,调用fp所指向的函数。

例如数组ab分别为[1,2,3][4,5,6],则依次以(1,4)(2,5)(3,6)作为参数调用fp所指向的函数。

裁判测试程序样例:

 

一个可能的函数被调用进行测试的例子像这样: ** 注意: 实际的测试程序可能与下面这个程序很不同! #include <stdio.h> void isFactorOf(int x, int y){ if(x % y) printf("%d is not a factor of %d.\n", y, x); else printf("%d is a factor of %d.\n", y, x); } void proceed(int *a, int *b, int size, void (*fp)(int x, int y)); int main() { int n; scanf("%d", &n); int a[n], b[n]; for(int i=0; i<n; i++) scanf("%d", a+i); for(int i=0; i<n; i++) scanf("%d", b+i); proceed(a, b, n, isFactorOf); return 0; } /* 你的代码将被嵌到这里 */

输入样例:

3
1 10 15
5 5 10

输出样例:

5 is not a factor of 1.
5 is a factor of 10.
10 is not a factor of 15.
void proceed(int *a, int *b, int size, void (*fp)(int x, int y))
{
    for(int i=0;i<size;i++)
    {
        (*fp)(a[i],b[i]);
    }
}

6-3 万能的排序函数

分数 20

全屏浏览题目

切换布局

作者 吴敏华

单位 首都师范大学

有n个整数,需要对他们进行各种排序:升序排序、降序排序、按个位数升序排序、按十位数降序排序,为了提高代码的重用性,可以用指向函数的指针作排序函数的参数。

程序输入n+2个整数:

第一行是整数n,表示后面有n个整数需要排序

第二行是待排序的n个整数

第三行是排序需求,分别是1-4,依次表示升序排序、降序排序、按个位数升序排序、按十位数降序排序

程序的输出是排好序的n个整数,两个整数之间用空格隔开

函数接口定义:

需要实现以下函数:

 

void sort(int *p, int (*compare)(int a,int b), int N); int Descending(int a, int b); int bit1_Des(int a, int b);

其中 p 是数据的首地址, N 是需要排序的数据个数, compare 是指向函数的指针。sort函数用选择法进行排序

裁判测试程序样例:

 

#include <stdio.h> void sort(int *p, int (*compare)(int a,int b), int N); int Ascending(int a, int b); int Descending(int a, int b); int bit0_Asc(int a, int b); int bit1_Des(int a, int b); int main() { int n=10,k; int *s,*p; int (*fun)(int,int); scanf("%d",&n); p=(int*)malloc(n*sizeof(int)); for(s=p; s<p+n; s++) scanf("%d",s); scanf("%d",&k); switch(k) { case 1:fun=Ascending; break; case 2:fun=Descending; break; case 3:fun=bit0_Asc; break; case 4:fun=bit1_Des; break; } sort(p,fun,n); for(s=p; s<p+n-1; s++) printf("%d ",*s); printf("%d\n",*s); return 0; } int Ascending(int a, int b) { return a>b; } int bit0_Asc(int a, int b) { return a%10>b%10; } /* 请在这里填写答案 */

输入样例:

11
886 461 856 581 514 272 197 182 564 121 894
3

输出样例:

461 581 121 272 182 514 564 894 856 886 197
void sort(int *p, int (*compare)(int a,int b), int N)
{
	for(int i=0;i<N-1;i++)
	{
		int k=i;
		for(int j=i+1;j<N;j++)
		{
			if((*compare)(p[k],p[j]))
				k=j;
		}
		if(k!=i)
		{
			int temp=p[i];
			p[i]=p[k];
			p[k]=temp;
		}
	}
}
int  Descending(int a, int b)
{
	return a < b; 
}

int bit1_Des(int a, int b)
{
    return a/10%10 < b/10%10;
}

6-4 利用函数指针实现递增或递减排序

分数 20

全屏浏览题目

切换布局

作者 C专题课程组-humin

单位 浙江大学

本题要求实现一个函数,根据主程序运行提示完成一组整数的递增或递减排序。

函数接口定义:

 

static void sortAorD(int *array, int n, int (*compare)(int a, int b))

其中array是要排序的数组的起始地址,n是要排序的数的个数,compare 是函数指针,具体含义见给出的程序。

裁判测试程序样例:

本程序运行时,若输入符号A, 则按照升序排序,输入符号D,则按降序排序。

 

#include <string.h> static int array[20]; static int ascending(int a, int b); static int descending(int a, int b); static void sortAorD(int array[ ], int n, int (*compare)(int a, int b)) ; typedef struct { char name; int (*cmd)(int a, int b); }SortCmd; int main() { int k,n; char cmdType; scanf("%c", &cmdType); scanf("%d", &n) ; SortCmd cmds[]={ {'A', ascending}, /* Ascending */ {'D', descending} /*Descending */ }; for (k = 0; k<n; k++) scanf("%d", &array[k]); for (k = 0; k < sizeof(cmds)/sizeof(cmds[0]); k++) { if (cmdType==cmds[k].name) sortAorD(array, n, cmds[k].cmd); } for (k=0; k<n; k++) printf("%d ", array[k]); } static int ascending(int a, int b) { return (a>=b); } static int descending(int a, int b) { return (a<b); }

输入样例:

在这里给出一组输入。例如:

A
15
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

输出样例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
static void sortAorD(int *array, int n, int  (*compare)(int a, int b)) {
  for (int i= 0; i< n-1; i++) 
  { 
    for (int j= 0; j< n-1-i; j++)
    {
        if ((*compare)(array[j],array[j+1]))
        {
            int temp = array[j];
            array[j] = array[j+1];
            array[j+1] = temp;
        }
    }
  }
}

6-5 进步排行榜的比较函数

分数 20

全屏浏览题目

切换布局

作者 黄龙军

单位 绍兴文理学院

设学生信息的结构体设计如下:

struct Stu {
    string username;  //用户名
    int diff;   //进步总数
    int total;  //解题总数
};

解题进步排行榜中,按进步总数diff及解题总数toatal生成排行榜。要求先输入n个学生的信息;然后按diff降序排列;若diff相同,则按toatal降序排列;若difftoatal都相同,则按用户名username升序排列。

要求实现一个比较函数cmp,该函数作为sort()函数的第三个参数。

函数接口定义:

 

bool cmp(Stu s, Stu t);

其中 s 和 t 是用户传入的两个Stu类型的结构体参数。

裁判测试程序样例:

 

#include <iostream> #include <string> #include <algorithm> using namespace std; bool cmp(Stu s, Stu t); //输入整数n,再输入n个学生的信息,按要求排序后输出,处理到文件尾 int main() { int n; while(cin>>n) { Stu a[n]; int i; for(i=0; i<n; i++) cin>>a[i].username>>a[i].diff>>a[i].total; sort(a, a+n, cmp); for(i=0; i<n; i++) cout<<a[i].username<<" "<< a[i].diff<<" "<<a[i].total<<endl; } return 0; }

输入样例:

10
usx15131 21 124
usx15101 27 191
usx15107 24 154
usx15113 31 124
usx15117 27 191
usx15118 21 124
usx15119 22 117
usx15121 43 214
usx15128 21 124
usx15136 27 199

输出样例:

usx15121 43 214
usx15113 31 124
usx15136 27 199
usx15101 27 191
usx15117 27 191
usx15107 24 154
usx15119 22 117
usx15118 21 124
usx15128 21 124
usx15131 21 124
bool cmp(Stu s, Stu t)
{
    if(s.diff!=t.diff)
    {
        return s.diff>t.diff;
    }
    else
    {
        if(s.total!=t.total)
        {
            return s.total>t.total;
        }
        else
        {
            return s.username<t.username;
        }
    }
}

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值