第十二周课后作业

6-24 实验8_3_设计函数

1.题目

设计函数将二维数组M中每列的最小元素,依次放入一维数组x中,二维数组M的行数为n,列数为m。

输入第一行为两个整数n、m,代表二维数组M的行数与列数,n、m的范围均是1—100。然后是n*m个整数,即二维数组M的元素。输出x数组中的元素,每个元素用空格分隔。

函数接口定义:
void findMin(int M[][MAX],int x[],int n,int m);
其中 M , x, n 和 m 都是用户传入的参数。 M 代表二维数组;x为保存结果的一维数组;n 和 m 为二维数组的行数和列数;MAX 为常量,本题中为100 ;函数没有返回值。

2.思路

按列遍历数组,每列中查找最小元素,记录在x数组中

3.代码

void findMin(int M[][MAX],int x[],int n,int m) {
    for (int i = 0; i < m; i ++) {
        int min = M[0][i];
        for (int j = 0; j < n; j ++) {//遍历每列
            if(min> M[j][i]){
                min=M[j][i];
            }
        }
        x[i] = min;
    }
}

6-28 实验10_1_英超一

1.题目

英格兰足球超级联赛(Premier League),通常简称“英超”,是英格兰足球总会属下的最高等级职业足球联赛。

英超联赛采取主客场双循环赛制比赛,每支队伍与各球队对赛两次,主客各一次。由1995/96赛季开始参赛球队由22队减至20队,每支球队共进行38场赛事,主场和客场比赛各有19场。每场胜方可得3分,平局各得1分,负方得0分,按各队于联赛所得的积分排列。

现请你写一个函数来计算某支球队的当前的积分。

输入:

只有一行,为一个字符串。该字符串包含不多于40个字符,每个字符代表该队一轮比赛的结果。字符串中只包含W(代表该队某轮取胜)、D(代表该队某轮和对手打平)和L(代表该队某轮失利)三种字符。

输出:

只有一个整数,为根据输入数据,计算出的该队当前的积分。

函数接口定义:
int        getScore(char * s) ;
其中 s 为用户传入的参数,为指向某队当前的全部赛果的指针。函数须返该队当前积分。

2.思路

逐个读取字符,根据三种情况累积总分

3.代码

int getScore(char *s){
	int score=0;
	for(int i=0;i<40;i++){
		if(s[i]=='W'){
            score+=3;
        }
		else if(s[i]=='D'){
            score+=1;
        }
        else if(s[i]=='L'){//不写也行
            score+=0;
        }
	}
	return score;
}

6-29 实验10_2_动态内存分配函数_1

1.题目

1、设计函数int * create(int n) ;,根据整数n创建一个长度为n的整型动态一维数组,并返回动态数组第一个元素的地址。

2、设计函数 void cal(int * array, int size) ;该函数可计算array 所指向的动态一维数组中存储的size个整数的和及平均值,同时寻找其中的最大值、最小值。

输入共两行,第一行为一个整数n(0<n<100)。第二行为n个用空格分隔的整数。第一行在主函数中输入,第二行需在函数cal中输入,并存储在 array 所指向的动态一维数组中。

输出共5行,前四行依次为和、平均值(精确到小数点后两位)、最大值、最小值。最后一行按原样输出输入的那n个整数。前四行需在函数cal中输出,最后一行由主函数输出。

测试数据保证所有整数可以用int型存储。出题者存储浮点数时用的是 float。

函数接口定义一:
int * create(int n) ;
其中 n 为整数数组的长度; 函数需返回动态数组第一个元素的地址。如果没有获得内存则返回NULL。

函数接口定义二:
void cal(int * array, int size) ;
其中 array 和 size 都是用户传入的参数。 array 为整数数组的首地址; size 是数组中所存储的整数的个数。函数没有返回值。

2.思路

int * create(int n)使用参数n,使用malloc进行动态内存分配
void cal(int * array, int size)先进行数组输入,之后对数组计算和、均值、最大值、最小值并逐行输出,需要遍历一维数组之后进行数据处理,实际上可以用一次遍历完成。

3.代码

int * create(int n) {
	int *arr=NULL;
    if(n>0){
        arr = (int*)malloc(sizeof(int) * n);//动态分配内存
    }
	return arr;
}

void cal(int * array, int size){
    for (int i = 0; i < size; ++i) {//输入
        scanf("%d",&array[i]);
    }
    //数据处理的初始化
    int sum = array[0];
    int max = array[0];
    int min = array[0];
    for (int i = 1; i < size; ++i) {
        sum += array[i];
        if(array[i] > max){
            max = array[i];
        }
        if(array[i] < min){
            min = array[i];
        }
    }
    double avg = (double)sum/size;//sum和size计算均值
    printf("%d\n",sum);
    printf("%.2f\n",avg);
    printf("%d\n",max);
    printf("%d\n",min);
}

6-31 实验10_4_设计函数 locatesubstr

1.题目

设计函数 char *locatesubstr(char *str1,char *str2),查找str2指向的字符串在str1指向的字符串中首次出现的位置,返回指向该位置的指针。若str2指向的字符串不包含在str1指向的字符串中,则返回空指针NULL。
注意这里必须使用指针而不是数组下标来访问字符串。

函数接口定义:
char *locatesubstr(char *str1,char *str2);
其中 str1 和 str2 都是用户传入的参数,其含义如题面所述 。若查找成功则返回指向该位置的指针,若失败则返回空指针。

2.思路

核心考点是字符串匹配,最简单的思路遍历str1的基础上,每次比较str1目前指针之后的若干字符和str2之间的字符是否相等。
字符串匹配还可以使用KMP算法进行求解。可以课下了解

3.代码

char *locatesubstr(char *str1,char *str2){
	int i=0;
	for(int i=0;*(str1+i)!='\0';i++){//遍历str1
		for(int j=0;*(str1+i+j)==*(str2+j);j++){//str1+i之后的若干元素进行字符比较,直到不相等或者字串结束
			if(*(str2+j+1)=='\0') //str2结束
                return str1+i;//成功情况
		}
	}
	return NULL;//失败情况
}

6-32 实验10_5_指针数组初步

1.题目

已知一个总长度不超过10000的字符串,字符串中只包含大写字母“A—Z”、小写字母“a—z”和空格‘ ’。空格用于分割单词,空格的个数不超过1000个。你的任务是将字符串中用空格分隔的单词打印出来。
你要按照如下要求完成任务:
1.利用指针数组指向每个单词的开始位置。
2.把字符串中单词结束后的空格改为“\0”,然后使用指针数组将每个单词打印出来。

测试用例保证至少有一个单词。

函数接口定义:
int getString( char * source , char *strPtr[] ) ;
其中 source 和 strPtr 都是用户传入的参数。 source 为待处理字符串; strPtr 是保存各个单词开始位置的指针数组。函数返回值为单词的个数。

2.思路

遍历source字符串,重点在于空格情况的处理以及指针传递的过程中单词如何截断。

3.代码

int getString( char * source , char *strPtr[] ) {
    int strPtr_index = 0, source_index = 0;
    while (source[source_index]!='\0') {
        while(source[source_index]!='\0' && source[source_index]==' '){//处理第一个单词之前的空格
               source_index++;
        }
        if (source[source_index]!='\0') {//空格处理完毕
            strPtr[strPtr_index] = &source[source_index];//记录单词起始位置
            strPtr_index++;//统计单词数
            while (source[source_index] && source[source_index] != ' '){
                source_index++;
            } //处理单词
            source[source_index] = '\0';//单词的最后一位为终止符,使得strPtr每次指向的是一个单词而不是一长串
            source_index++;//为下一轮循环做准备,否则直接跳出循环
        }
    }
    return strPtr_index;
}

7-49 实验8_7_蛇形矩阵

1.题目

蛇形矩阵是一个n*n的矩阵,将整数1到n*n按照蛇形的顺序装入一个 n*n 的蛇形矩阵中,如样例所示分别为5阶和10阶蛇形矩阵。

输入格式:
只有一行,为一个整数n,代表蛇形矩阵的阶数,n的范围是1—100。

输出格式:
共n行,为蛇形矩阵。每行的每个元素用空格分隔,注意最后一个数的后面为换行符。

2.思路

定义n*n的矩阵数组,按照蛇形矩阵的数学规律填入对应的数据,或者按照运动顺序依次找到待填写的位置填入元素,此处采用第二种

3.代码

#include <stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    int snake[n][n];
    int i=0,j=0;
    snake[0][0]=1;
    int cnt=1;
    int dir=1;
    while(cnt<n*n){
        cnt++;
        if(dir==1){//向下运动
            i++;
            snake[i][j]=cnt;
            if(j==0){
                dir=2;
            }else if(j==n-1){
                dir=4;
            }
        }else if(dir==2){//右上运动
            i--;
            j++;
            snake[i][j]=cnt;
            if(i==0&&j!=n-1){
                dir=3;
            }else if(j==n-1){
                dir=1;
            }else{
                dir=2;
            }
        }else if(dir==3){//向右运动
            j++;
            snake[i][j]=cnt;
            if(i==0){
                dir=4;
            }else if(i==n-1){
                dir=2;
            }
        }else if(dir==4){//左下运动
            i++;
            j--;
            snake[i][j]=cnt;
            if(j==0&&i!=n-1){
                dir=1;
            }else if(i==n-1){
                dir=3;
            }else{
                dir=4;
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%d",snake[i][j]);
            if(j<n-1) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

7-56 实验10_9_指针数组进阶

1.题目

已知正整数n,n的范围是1—100。你要从键盘读入n个字符串,每个字符串的长度不确定,但是n个字符串的总长度不超过100000。你要利用字符指针数组将这n个字符串按照ASCII码顺序进行升序排序,然后再打印到屏幕上。字符串中可能包含ASCII码中的任意字符,每个字符串以换行符结束输入。

要求:不允许定义如char str[100][100000];这样的二维数组,因为会极大的浪费内存空间。你应定义char str[100000];这样的存储空间,将n个字符串连续的存储在一维字符空间内,然后将这n个字符串的起始位置保存在字符指针数组中,再进行排序操作。

输入格式:
输入一个正整数n,代表待排序字符串的个数,n不超过100,然后是n个字符串,每个字符串的长度不确定,但至少包含1个字符。n个字符串的总长度不会超过100000。

输出格式:
排序后的n个字符串,每个字符串占一行。

2.思路

输入部分,设置一个总数组存储所有字符串结果,一个指针数组,每个元素均指向字符存储的首位置;
排序中对字符串的比较使用strcmp函数,可使用基础的排序方法,例如冒泡排序、选择排序等

3.代码


#include<stdio.h>
#include<stdlib.h>
int main()
{
    int n;
    scanf("%d\n",&n);//字符串个数
    
    char str_all[100000]={0};//字符串总长度
    char *s[100]={0};//存储每个字符串的位置
    s[0]=str_all;//第一个字符串的起始位置
    for(int i=0;i<n;i++){
        gets(s[i]);//读取第i个字符串,还是存在str_all里面
        if(i<n-1){//不是最后一个字符串
            s[i+1]=s[i]+strlen(s[i])+1;//设置下一个字符串在str_all的起始位置
        }
    }
    for(int i=0;i<n;i++){//类似于冒泡排序读取元素
        for(int j=0;j<n-i-1;j++){
            if(strcmp(s[j],s[j+1])>0){
                char *temp=s[j+1];
                s[j+1]=s[j];
                s[j]=temp;
            }
        }
    }
    
    for(int i=0;i<n;i++){//输出
        puts(s[i]);
    }

    return 0;
}

7-60 实验11_3_结构排序

1.题目

有n名学生,每个学生的属性包括姓名与总成绩。已知学生的姓名与总成绩,你的任务是将学生的信息按照以下方式排序:首先比较总成绩,总成绩高的在前面,总成绩低的在后面,当总成绩相同时,你要比较学生的姓名,姓名字典序小的同学在前面,姓名字典序大的同学在后面(ASCII码顺序)。n的范围是1—100;学生的姓名中只能包含大小写字母,不会超过20个字符;总成绩为整数。

要求:在本题中,你要设计一个结构来存储学生的信息。在此结构中,需要有一个字符数组来存储姓名,一个整型变量存储总成绩。

输入格式:
首先输入一个正整数n,代表学生的数量,1<=n<=100;每名学生的信息按照姓名、总成绩的顺序输入(空格分开),每名学生信息占一行。具体格式见样例。

输出格式:
n名学生的信息,姓名占一行,总成绩占一行,输出顺序要按照题目的要求,每名同学的信息后都再输出一个空行。
注意:每名同学的信息后都再输出一个空行。

2.思路

主要考查结构体的定义和使用,定义结构体数组之后,按照某个元素对结构体整体进行排序,排序中的比较项仅仅考虑结构体里面的成绩项,移动元素时移动整个结构体。
注意结构体的定义、元素访问即可。

3.代码

#include <stdio.h>
#include <string.h>

typedef struct student{
	char name[21];//名字
	int grade;//成绩
};

int main()
{
    //输入
    int n;
	scanf("%d",&n);

	struct student stu[n];
	for(int i=0;i<n;i++){
		scanf("%s %d",stu[i].name,&stu[i].grade);
	}
    //冒泡排序
	for(int i=1;i<=n-1;i++){//冒泡排序进行两两比较
		for(int j=0;j<n-i;j++){
			if(stu[j].grade<stu[j+1].grade){
				struct student temp=stu[j];
				stu[j]=stu[j+1];
				stu[j+1]=temp;
			}
			if(stu[j].grade==stu[j+1].grade){//相等则比较字符串大小
                if(strcmp(stu[j].name,stu[j+1].name)>0){
                    struct student temp=stu[j];
				    stu[j]=stu[j+1];
			    	stu[j+1]=temp;
                }
			}
		}
	}
	//输出
    for(int i=0;i<n;i++){
		printf("Name:%s\n",stu[i].name);
		printf("total:%d\n\n",stu[i].grade);
	}
	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值