c/c++零基础坐牢第九天
c/c++从入门到入土(9)
开始时间2023-04-27 19:27:23
结束时间2023-04-27 23:27:35
前言:哈哈,今天是五一假期前的狂欢了?不少明天没课的同学都飞奔回家咯。咳咳,都来玩星穹铁道,不玩星穹铁道都是轨子,我铁道兵要来打轨子啦!经过几天的沉淀,对函数多少有些理解,咱们今天就来进行函数编程的相关练习!
实验四 函数程序设计
第一题 应用函数将整数转换成字符串
一.问题描述
完成程序,设计实现函数int itoa(long int x,char a[]),其功能为将给定的整数x转换成字符串存储在a数组中。 函数接口定义: int itoa(long int i,char a[]);/*功能为将给定的整数x转换成字符串存储在a数组中*/ 裁判测试程序样例: #include <stdio.h> #define N 12 /* 请在这里填写答案 */ int main(){ long int n; char a[N]; scanf("%ld",&n); itoa(n,a); printf("%s",a); return 0; } 输入格式: 请在一行中输入整数x的值。 输出格式: 对每一组输入的x,输出其字符串形式。 输入样例1: 72 输出样例1: 72 输入样例2: 0 输出样例2: 0 输入样例3: -512 输出样例3: -512 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.设计思路
既然是一道函数题,咱们首先看裁判样例,标准库函数下面宏定义N为12,主函数中声明长整型n,字符类数组a[N]然后输入n后便调用我们的自定义函数。我们要写的一个函数要满足的功能是将n又整型转换为字符型后存储,比如整型的72是一个数,但存入字符数组变为两个字符‘7’,‘2’。那我们应该如何来做?首先我们将所给整数每个位置上的数单拎出来,将该数加上‘0’便将整型数字变为字符数字 ,依次做循环,循环截止时,便将数字完全转化为各位的字符数字。值得一提,若所给数字为负数,那么我们要先判断符号,为负数,将数组内的元素设为-,然后将数字变为正数形式。
三.源代码
int itoa(long int i, char a[]) { int t=0,flag=1; char temp; if(i<0) { flag=-1; i=-i; } do { a[t++]=i%10+'0'; }while(i/=10); if(flag==-1) { a[t++]='-'; } a[t]='\0'; for(t--,i=0;i<t;i++,t--) { temp=a[t]; a[t]=a[i]; a[i]=temp; } return a[N]; }
第二题 应用函数实现矩阵乘法
一.问题描述
完成程序,设计实现函数void f(int a[],int b[],int c[],int m,int n,int t),其功能为计算给定的两个整型数组(一个为m行n列,一个为n行t列)的乘积矩阵。 函数接口定义: void f(int a[],int b[],int c[],int m,int n,int t);/*功能为计算给定的矩阵a(m行n列)和矩阵b(n行t列)的乘积矩阵c*/ 裁判测试程序样例: #include <stdio.h> /* 请在这里填写答案 */ int main(){ int i,j,a[3][4],b[4][3],c[3][3]; for(i=0; i<3; i++) for(j=0; j<4; j++) scanf("%d",&a[i][j]); for(i=0; i<4; i++) for(j=0; j<3; j++) scanf("%d",&b[i][j]); f(a[0],b[0],c[0],3,4,3); for(i=0; i<3; i++){ for(j=0; j<3; j++) printf("%5d",c[i][j]); printf("\n"); } } 输入格式: 首先输入整型数组a[3][4]的各元素的值,再输入整型数组b[4][3]的各元素的值,数据中间以空格为间隔。 输出格式: 对于输入的a数组和b数组,输出a和b的乘积矩阵c[3][3],其中每个元素显示格式为:占5列,右对齐。 输入样例: 1 2 3 4 2 3 4 5 3 4 5 6 1 2 3 2 3 4 3 4 5 4 5 6 输出样例: 30 40 50 40 54 68 50 68 86 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.设计思路
看主函数,声明了i,j,二维数组a,二维数组b,和乘积二维数组c,在第一个嵌套循环中给a数组赋值,在第二个循环中给b数组赋值,接着调用函数。在函数中我们要做到的功能是,给到a数组和b数组,以矩阵相乘的形式得到c数组。要知道矩阵相乘第一行第一个数为矩阵a的第一行成矩阵b第一列,第一行第二个数为第一行第二个数为a的第一行乘b的第一列,第一行第三个数为a的第一行乘b的第三列,第二列同理。一个我们要做循环不仅满足相乘还要相加。
三.源代码
void f(int a[3][4],int b[4][3],int c[3][3],int m,int n,int t) { int i,j,k; for(i=0;i<m;i++) { for(j=0;j<t;j++) { int sum=0; for(k=0;k<n;k++) { sum+=(a[i][k]*b[k][j]); } c[i][j]=sum; } } }
第三题 应用递归函数求解N阶勒让德多项式
一.问题描述
完成程序,设计实现函数double p(int n,int x),其功能为计算给定参数n和x的N阶勒让德多项式
的值。N阶勒让德多项式
的递归公式如下所示:
函数接口定义: double p(int n,int x);/*功能为计算给定参数n和x的N阶勒让德多项式的值*/ 裁判测试程序样例: #include <stdio.h> /* 请在这里填写答案 */ int main(){ int x,n; scanf("%d%d",&n,&x); printf("P%d(%d)=%.1f\n",n,x,p(n,x)); return 0; } 输入格式: 请在一行中输入整数n和x的值,数据中间以空格为间隔。 输出格式: 对每一组输入的n和x,按照以下格式输出N阶勒让德多项式pn(n , x)的值。 P< n >(< x >)=<值>。 输入样例: 2 2 输出样例: P2(2)=2.0 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.设计思路
看主函数,声明两个基本整型x和n,然后输入x,n。函数功能为计算给定参数n和x的N阶勒让德多项式。首先这个勒让德多项式是跟n有关的,分三种情况,n=0,n=1,n>1.分别计算。
三.源代码
double p(int n,int x) { if(n==0) return 0; else if(n==1) return x; else if(n>1) return ((2*n-1)*x-p(n-1,x)-(n-1)*p(n-2,x))/n; }
第四题 应用递归函数实现起泡排序
一.问题描述
完成程序,设计实现递归函数void sort(int a[],int n),其功能为使用“起泡法”对a数组存储的n(n<=20)个数按从大到小排序,排列后任然存储a数组中。 函数接口定义: void sort(int a[],int n);/*功能为使用“起泡法”对a数组存储的n(n<=20)个数按从大到小排序,排列后任然存储a数组中*/ 裁判测试程序样例: #include <stdio.h> #define N 20 /* 请在这里填写答案 */ int main(){ int a[N],i,n; scanf("%d",&n); if(n>20) printf("error data"); else{ for(i=0; i<n; i++) scanf("%d",&a[i]); sort(a,n); for(i=0; i<n; i++) printf("%5d",a[i]); printf("\n"); } return 0; } 输入格式: 请在第一行中输入整数n的值,表示数据的个数。 在第二行中输入n个无序整数,数据中间以空格为间隔。 输出格式: 对每一组输入的n个无序整数,输出按照从小到大顺序的排序结果,其中每个数显示格式为:占5列,右对齐。 输入样例1: 10 1 2 3 4 5 0 9 8 7 6 输出样例1: 9 8 7 6 5 4 3 2 1 0 输入样例2: 45 输出样例2: error data 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.设计思路
看裁判程序样例,头文件下方宏定义N为20,在主函数中,首先声明i,n和数组a,输入n的值,以n的值进行判断n<20程序继续走,从键盘输入数组a,调用sort函数,注意!在c++中sort函数在库中存在,但在c中没有,此处给出sort函数的自定义。函数功能为将数组a从大到小排序,存进数组a中。冒泡排序在趣味算法里讲过,不赘述嗷。
三,源代码
void sort(int a[N],int n) { int i,j,temp; for(i=0;i<n-1;i++) { for(j=0;j<n-1-i;j++) { if(a[j]<a[j+1]) { temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } } }
第五题 应用函数求最大公约数
一.问题描述
完成程序,设计实现函数int gcd(int a,int b),其功能为计算给定的两个正整型数a和b的最大公约数。 函数接口定义: int gcd(int a,int b);/*功能为计算给定的两个正整型数a和b的最大公约数*/ 裁判测试程序样例: #include <stdio.h> /* 请在这里填写答案 */ int main(){ int a,b; scanf("%d%d",&a,&b); printf("%d",gcd(a,b)); return 0; } 输入格式: 请在一行中输入整数a和b的值,数据中间以空格为间隔。 输出格式: 对每一组输入的a和b,输出它们的最大公约数。 输入样例: 24 36 输出样例: 12 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.设计思路
在主函数中,首先声明整型a,b,然后给a,b赋值,输出a,b的最大公约数。很显然,在函数中我们要求解ab之间的最大公约数,我们怎么做呢,定义两个整型n和r,用一个数a取余一个数b,剩下的值给到r作为循环表达式,如果a能够取余b,则把a的值赋给b,剩下的值r赋给a,继续循环,最后a的值为最大公约数。
三.源代码
int gcd(int a,int b) { int n,r; while(r=b%a) { b=a; a=r; } n=a; return n; }
第六题 方程的根
一.问题描述
(谭浩强,《C程序设计(第四版)》,清华大学出版社:第七章,P218,第2题) 完成程序,设计实现函数void f(double a,double b,double c),其功能为输出方程的根,要求考虑a=0、a=0&b=0、
、
等情况。 函数接口定义: void f(double a,double b,double c);/*功能为输出一元二次方程的根,要求考虑参数的所有情况*/ 裁判测试程序样例: #include <stdio.h> #include <math.h> /* 请在这里填写答案 */ int main(){ double a,b,c; scanf("%lf%lf%lf",&a,&b,&c); f(a,b,c); return 0; } 输入格式: 请在一行中输入方程参数a、b和c的值,数据中间以空格为间隔。 输出格式: 对每一组输入的方程参数,输出方程的根。 输入样例1: 1.0 2.0 3.0 输出样例1: -1.000000+1.414214i,-1.000000-1.414214i 输入样例2: 1.0 2.0 1.0 输出样例2: -1.000000 输入样例3: 0.0 2.0 2.0 输出样例3: -1.000000 输入样例4: 1.0 4.0 1.0 输出样例4: -0.267949,-3.732051 输入样例5: 0.0 0.0 1.0 输出样例5: error data 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.设计思路
分析裁判程序,在标准库函数下有数学库文件头,引入双精度浮点型a,a,c,并对a,b,c赋值,再调用函数。
三.源代码
void f(double a,double b,double c) { double x,x1,x2,m,n,dt; if(a==0&&b==0) printf("error data\n"); else if(a==0&&b!=0) { x=-c/b; printf("%f",x); } else if(a!=0) { dt=b*b-4*a*c; if(dt==0) { x=((-b)+sqrt(dt))/(2*a); printf("%f",x); } else if(dt>0) { x1=((-b)+sqrt(dt))/(2*a); x2=((-b)-sqrt(dt))/(2*a); printf("%f,%f",x1,x2); } else if(dt<0) { m=-b/(2*a); n=sqrt(-dt)/(2*a); printf("%f+%fi,%f-%fi",m,n,m,n); } } }
第七题 矩阵转置
一.问题描述
完成程序,设计实现函数void f(int a[][N],int n),其功能为实现一个给定的n*n(n<=N,N=10)的二维整形数组转置。 函数接口定义: void f(int a[][N],int n);/*功能为实现一个给定的n*n(n<=N,N=10)的二维整形数组转置*/ 裁判测试程序样例: #include <stdio.h> #define N 10 /* 请在这里填写答案 */ int main(){ int a[N][N],n,i,j; scanf("%d",&n); if(n<1||n>10) printf("error data"); else{ for(i=0; i<n; i++) for(j=0; j<n; j++) scanf("%d",&a[i][j]); f(a,n); for(i=0; i<n; i++){ for(j=0; j<n; j++) printf("%5d",a[i][j]); printf("\n"); } } return 0; } 输入格式: 请在第一行中输入二维矩阵a[n][n]的维数大小n的值。 然后输入该二维矩阵的元素的值,数据中间以空格为间隔。 输出格式: 对输入的二维矩阵,以方阵形式输出转置后的二维矩阵,其中每个元素显示格式为:占5列,右对齐。 输入样例1: 5 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 输出样例1: 1 6 11 16 21 2 7 12 17 22 3 8 13 18 23 4 9 14 19 24 5 10 15 20 25 输入样例2: 15 输出样例2: error data 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.程序设计
我们要做的功能是矩阵转置,也就是说,将二维数组的行全部变为列,将所有的列变为行。
三.源代码
void f(int a[][N],int n) { int i,j,t; for(i=0;i<n;i++) for(j=i+1;j<n;j++) { t=a[i][j]; a[i][j]=a[j][i]; a[j][i]=t; } }
第八题 最长单词
一.问题描述
完成程序,设计实现函数void f(char a[]),其功能为输出a[]存储的字符串中最长的单词,如有多个最长单词,则输出位置最靠前的。字符串的总长度小于100。 函数接口定义: void f(char a[]);/*输出a[]存储的字符串中最长的单词*/ 裁判测试程序样例: #include <stdio.h> #define N 100 /* 请在这里填写答案 */ int main(){ char c[N]; gets(c); f(c); return 0; } 输入格式: 请输入一行单词,总长度小于100。 输出格式: 对于输入的字符串,输出其中最长的单词。 输入样例: It adopts (greatest common denominator) principle to provide a union set of components that appear on every platform. 输出样例: denominator 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.源代码
void f(char a[]) { int pos,tpos,len=0,tlen=0; int i=0; do { if ((a[i]>='a' && a[i]<='z')||(a[i]>='A' && a[i]<='Z')) { if (!tlen)//记录字符位置和长度R tpos=i; tlen++; //printf("%d%d\n",tpos,tlen);//可查看字符位置和长度R } else { //printf("%d%d\n",pos,len);//查看上一步字符位置和长度R if (tlen>len)//此时单词结束与上一个单词长度进行比较R { pos=tpos; len=tlen; //printf("%d%d\n",pos,len);//可查看比较后结果R } tlen=0; } } while (a[i++]); for (i=0;i<len;i++) printf("%c",a[pos+i]);//打印最长单词R }
第九题 牛顿迭代法
一.问题描述
完成程序,设计实现函数double f(double a,double b,double c,double d,double x),其功能为运用牛顿迭代法求方程
在x附近的一个实根。 函数接口定义: double f(double a,double b,double c,double d,double x);/*功能为运用牛顿迭代法求给定方程在x附近的一个实根*/ 裁判测试程序样例: #include <stdio.h> #include <math.h> /* 请在这里填写答案 */ int main(){ double a,b,c,d,x; scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&x); printf("%lf\n",f(a,b,c,d,x)); return 0; } 输入格式: 请在一行中输入方程系数a、b、c、d和实数x,数据中间以空格为间隔。 输出格式: 对每一组输入的数据,输出牛顿迭代法求出的实根。 输入样例: 1.0 2.0 3.0 4.0 1.0 输出样例: -1.650629 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二..设计思路
具体过程:设 x* 是 f(x) = 0 的根,选取 x0 作为 x* 的初始近似值,过点 (x0,f(x0)) 作曲线 y = f(x) 的切线 L,L:y = f(x0) + f'(x0)(x - x0),则 L 与 x 轴交点的横坐标为:,称 x1 为 x* 的一次近似值。过点 (x1, f(x1)) 作曲线 y = f(x) 的切线,切线与 x 轴的交点横坐标为:
,称 x2 为 x* 的二次近似值。重复上述过程,得 x* 的近似值序列,其中:
称为 x* 的 n + 1 次近似值,上式称为牛顿迭代公式。
三.源代码
double f(double a,double b,double c,double d,double x)/*功能为运用牛顿迭代法求给定方程在x附近的一个实根*/ { double x0,f,f1; do { x0=x; f=((a*x0+b)*x0+c)*x0+d; f1=(3*x0*a+2*b)*x0+c; x=x0-f/f1; }while(fabs(x-x0)>=1e-3); return(x); }
第十题 学生成绩
一.问题描述
程序输入n(0<n<=10)名学生5门课程的成绩,分别调用函数实现以下功能: (1)设计实现函数void aver(int a[][5],double ave[],int n),其功能为计算每位学生的平均分。 (2)设计实现函数void couAver(int a[][5],double couAve[5],int n),其功能为计算每门课程的平均分。 (3)设计实现函数void max(int a[][5],char courName[][10],int n),其功能为输出所有分数中最高分数对应的学生的序号(从1开始)、课程名称及成绩,每个最高分的信息占一行。 (4)设计实现函数double averVari(double ave[],int n),其功能为计算n名同学的平均分方差:
其中
为某一学生的平均分。 函数接口定义: void aver(int a[][5],double ave[],int n);/*功能为计算每位学生的平均分*/ void couAver(int a[][5],double couAve[5],int n);/*功能为计算每门课程的平均分*/ void max(int a[][5],char courName[][10],int n);/*功能为输出所有分数中最高分数对应的学生的序号(从1开始)、课程名称及成绩,每个最高分的信息占一行*/ double averVari(double ave[],int n);/*功能为计算n名同学的平均分方差*/ 裁判测试程序样例: #include <stdio.h> #include <math.h> #define N 10 /* 请在这里填写答案 */ int main(){ char courName[5][10];/*课程名称*/ int n,i,j,a[N][5];/*n学生人数,a学生成绩*/ double ave[N],couAve[5];/*ave学生平均成绩,couAve课程平均成绩*/ for(i=0; i<5; i++) gets(courName[i]); scanf("%d",&n); for(i=0; i<n; i++) for(j=0; j<5; j++) scanf("%d",&a[i][j]); aver(a,ave,n); printf("Average:\n"); for(i=0; i<n; i++){ printf("[No.%d]Average=%f\n",i+1,ave[i]); } couAver(a,couAve,n); printf("CourseAverage:\n"); for(i=0; i<5; i++){ printf("[%s]CourseAverage=%f\n",courName[i],couAve[i]); } max(a,courName,n); printf("Averagevariance=%f",averVari(ave,n)); return 0; } 输入格式: 首先输入5门课程的课程名称,每门课程名称占一行,且长度小于10字符。 再输入学生人数n,n小于10。 再输入n名学生的5门课程成绩,每名同学的成绩占一行,数据中间以空格为间隔。 输出格式: 对每一组输入的学生成绩,首先以以下格式输出每位学生的平均分,每位同学占一行:[No.<序号>]Average=<平均成绩> 再者以以下格式输出每门课程的平均分,每门课程占一行:[<课程名称>]CourseAverage=<课程平均分> 再者以以下格式输出最高分数对应的学生的序号(从1开始)、课程名称及成绩,每个最高分的信息占一行:No.<序号>[<课程名称>]=成绩 最后以以下格式输出输出n名同学的平均分方差:Averagevariance=<平均分方差>。 输入样例: YuWen ShuXue YingYu DiLi LiShi 3 100 98 87 76 100 95 78 79 69 89 100 59 92 85 87 输出样例: Average: [No.1]Average=92.200000 [No.2]Average=82.000000 [No.3]Average=84.600000 CourseAverage: [YuWen]CourseAverage=98.333333 [ShuXue]CourseAverage=78.333333 [YingYu]CourseAverage=86.000000 [DiLi]CourseAverage=76.666667 [LiShi]CourseAverage=92.000000 Max: No.1[YuWen]=100 No.1[LiShi]=100 No.3[YuWen]=100 Averagevariance=18.728889 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB
二.源代码
void aver(int a[][5],double ave[],int n) /*功能为计算每位学生的平均分*/ {int i,j; double sum; for(i=0;i<n;i++) { for(j=0;j<5;j++) { sum+=a[i][j]; } ave[i]=sum/5; sum=0; } } void couAver(int a[][5],double couAve[5],int n) /*功能为计算每门课程的平均分*/ {int i,j; double s; for(i=0;i<5;i++) { for(j=0;j<n;j++) { s+=a[j][i]; } couAve[i]=s/n; s=0; } return 0; } void max(int a[][5],char courName[][10],int n) { int b[50]={1,2,3},c[50];//b数组存学号 c数组存成绩 char d[50][10]={'\0'} ;//d数组存科目 int e=a[0][0]; int i,j,k=0,m; printf("Max:\n"); for(i=0;i<n;i++) { for(j=0;j<5;j++) { if(e<a[i][j]) { e=a[i][j]; } } }//找到最大值 for(i=0;i<n;i++) { for(j=0;j<5;j++) { if(e==a[i][j]) { b[k]=i+1; for(m=0;courName[j][m]!='\0';m++) { d[k][m]=courName[j][m]; } c[k]=e; k++; } } } for(i=0;i<k;i++) { printf("No.%d[",b[i]); for(j=0;d[i][j]!='\0';j++) { printf("%c",d[i][j]); } printf("]=%d\n",c[i]); } } double averVari(double ave[],int n) /*功能为计算n名同学的平均分方差*/ { int i,j; double sum,sum2,fc; for(i=0;i<n;i++) { sum2+=ave[i]; sum=sum+ave[i]*ave[i]; } fc=sum/n-sum2*sum2/n/n; return(fc); }
总结:祝大家五一假期快乐!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程