第十二周课后作业
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;
}