哈工大C语言程序设计精髓MOOC 第十三周编程题

第13周——原来内存也可以这么玩,我是指针我怕谁

练兵区——编程题——不计入总分

2寻找最高分成绩的学生(4分)

题目内容:
下面程序的功能是用动态数组编程输入任意m个班学生(每班n个学生)的某门课的成绩,计算最高分,并指出具有该最高分成绩的学生是第几个班的第几个学生。其中,m和n的值由用户从键盘任意输入(不限定m和n的上限值)。

#include  <stdio.h>
#include  <stdlib.h>

void InputScore(int *p, int m, int n);
int  FindMax(int *p, int m, int n, int *pRow, int *pCol);
             
int main()
{ 
    int  *pScore, m, n, maxScore, row, col;
    printf("Input array size m,n:\n");
    scanf("%d,%d", &m, &n);  
    pScore = (int *)malloc(sizeof(int) * m * n); /* 申请动态内存 */
    
    if (pScore == NULL) 
    {
        printf("No enough memory!\n");
        exit(0); 
    }
    InputScore(pScore, m, n);
    maxScore = FindMax(pScore, m, n, &row, &col);
    
    printf("maxScore = %d, class = %d, number = %d\n", maxScore, row+1, col+1);                              
    free(pScore); /* 释放动态内存 */
    return 0;
}

/* 函数功能:输入m行n列二维数组的值 */
void InputScore(int *p, int m, int n) 
{
    int i, j;
    printf("Input %d*%d array:\n", m, n);
    for (i=0; i<m; i++)
    {
        for (j=0; j<n; j++)
        {
            scanf("%d", (p + i * n + j)); 
        }
    }
    
}
/*  函数功能:计算任意m行n列二维数组中元素的最大值,并指出其所在行列下标值 */
int  FindMax(int *p, int m, int n, int *pRow, int *pCol)    
{
    int  i, j, max = p[0];
    *pRow = 0; 
    *pCol = 0;                   
    
    
    
    for (i=0; i<m; i++)
    {
        for (j=0; j<n; j++)
        {
            if (max < p[i * n + j])        
            {
            	
                max = p[i * n + j];
                *pRow = i; /*记录行下标*/
                *pCol = j; /*记录列下标*/
            } 
        }  
    }  
    return max;                
}

3程序改错(4分)

题目内容:
下面程序的功能是输入m个学生(最多为30人)n门课程(最多为5门)的成绩,然后计算并打印每个学生各门课的总分和平均分。其中,m和n的值由用户从键盘输入。

#include  <stdio.h>
#define STUD   30      /* 最多可能的学生人数 */
#define COURSE 5       /* 最多可能的考试科目数 */
void  Total(int *pScore, int sum[], float aver[], int m, int n);
void  Print(int *pScore, int sum[], float aver[], int m, int n);
int main() {
	int     i, j, m, n, score[STUD][COURSE], sum[STUD];
	float   aver[STUD];
	printf("How many students?\n");
	scanf("%d", &m);
	printf("How many courses?\n");
	scanf("%d", &n);
	printf("Input scores:\n");

	for (i=0; i<m; i++) {
		for (j=0; j<n; j++) {
			scanf("%d", &score[i][j]);
		}
	}

	Total(*score, sum, aver, m, n);
	Print(*score, sum, aver, m, n);
	return 0;
}
void  Total(int *pScore, int sum[], float aver[], int m, int n) {
	int  i, j;
	for (i=0; i<m; i++) {
		sum[i] = 0;
		for (j=0; j<n; j++) {
			sum[i] = sum[i] + pScore[i*COURSE+j];
		}
		aver[i] = (float) sum[i] / n;
	}
}
void  Print(int *pScore, int sum[], float aver[], int m, int n) {
	int  i, j;
	printf("Result:\n");
	for (i=0; i<m; i++) {
		for (j=0; j<n; j++) {
			printf("%4d", pScore[i*COURSE+j]);
		}
		printf("%5d%6.1f\n", sum[i], aver[i]);
	}
}

4矩阵转置(4分)

题目内容:
下面程序的功能是用二维数组的列指针作为函数实参,计算并输出m×n阶矩阵的转置矩阵。其中,m和n的值由用户从键盘输入。已知m和n的值都不超过10。

#include <stdio.h>
#define M 10
#define N 10
void Transpose(int *a, int *at, int m, int n);
void InputMatrix(int *a, int m, int n);
void PrintMatrix(int *at, int n, int m); 
int main()
{
    int s[M][N], st[N][M], m, n;
    printf("Input m, n:\n");
    scanf("%d,%d", &m, &n);
    InputMatrix(*s, m, n);
    Transpose(*s, *st, m, n);
    printf("The transposed matrix is:\n");
    PrintMatrix(*st, n,  m); 
    return 0;
}
/* 函数功能:计算m*n矩阵a的转置矩阵at */
void Transpose(int *a, int *at, int m, int n)   
{ 
    int i, j;
    for (i=0; i<m; i++)
    {
        for (j=0; j<n; j++)
        {
            *(at + j*M + i) = *(a + i*M + j);
        }
    }
}
/* 函数功能:输入m*n矩阵a的值 */
void InputMatrix(int *a, int m, int n)   
{
    int i, j;
    printf("Input %d*%d matrix:\n", m, n);
    for (i=0; i<m; i++)
    {
        for (j=0; j<n; j++)
        {
            scanf("%d", (a + i * M +j)); 
        }
    }
}
/* 函数功能:输出n*m矩阵at的值 */
void PrintMatrix(int *at, int n, int m)   
{
    int i, j;
    for (i=0; i<n; i++)
    {
        for (j=0; j<m; j++)
        {
            printf("%-5d", *(at + i*M +j));
        }
        printf("\n");
    }
}

5在升序排序的数组中插入一个元素(4分)

题目内容:

用函数编程实现在一个按升序排序的数组中查找x应插入的位置,将x插入数组中,使数组元素仍按升序排列。
提示:插入(Insertion)是数组的基本操作之一。插入法排序算法的关键在于要找到正确的插入位置,然后依次移动插入位置及其后的所有元素,腾出这个位置放入待插入的元素。

#include<stdio.h>
#include<stdlib.h>

void inputArray(int *p, int size);
int findInsertPos(int *p, int size, int right, int left);

int main(){
	int n, *p = NULL, x;
	printf("Input array size:\n");
	scanf("%d", &n);
	p = (int *)malloc(sizeof(int) * (n + 1));
	if(p == NULL)
	{
		printf("No memory is left!");
		exit(1);
	}
	printf("Input array:\n");
	inputArray(p, n);
	printf("Input x:\n");
	scanf("%d", &x);
	int res = findInsertPos(p, x, n - 1, 0);
	
	// move
	for(int i = n - 1; i >= res; i--){
		*(p + i + 1) = *(p + i);
	}
	*(p + res) = x;
	
	printf("After insert %d:\n", x);
	for(int i = 0; i < n + 1; i++){
		printf("%4d", *(p + i));
	}
	free(p);
	return 0;
}


void inputArray(int *p, int size){
	for(int i = 0; i < size; i++){
		scanf("%d", p + i);
	}
}

int findInsertPos(int *p, int insertElement, int right, int left){
	if(right < left) return left;
	
	int middle = (right + left) / 2;
	
	if(*(p + middle) == insertElement){
		return middle;
	}
	else if(*(p + middle) > insertElement) {
		right = middle - 1;
	}else if(*(p + middle) < insertElement) {
		left = middle + 1;
	}
	
	return findInsertPos(p, insertElement, right, left);
	
}
  • 二分查找

6计算平均数、中位数和众数(4分)

题目内容:
在调查数据分析(Survey data analysis)中经常需要计算平均数、中位数和众数。用函数编程计算40个输入数据(是取值1—10之间的任意整数)的平均数(Mean)、中位数(Median)和众数(Mode)。中位数指的是排列在数组中间的数。众数是数组中出现次数最多的那个数(不考虑两个或两个以上的输入数据出现次数相同的情况)。

#include<stdio.h>
#include<stdlib.h>
#define N 40

int getMean(int *p, int size);
int getMedian(int *p, int size);
int getMode(int *p, int size);
void bubbleSort(int *p, int size);

int main(){
	
	int *p = NULL;
	p = (int *)malloc(sizeof(int) * N);
	if(p == NULL){
		printf("no memory is left!");
		exit(1);
	}
	
	printf("Input the feedbacks of 40 students:\n");
	for(int i = 0; i < N; i++){
		scanf("%d", p + i);
	}
	
	int mean = getMean(p, N);
	int median = getMedian(p, N);
	int mode = getMode(p, N);
	
	printf("Mean value=%d\n", mean);
	printf("Median value=%d\n", median);
	printf("Mode value=%d\n", mode);
	free(p);
	return 0;
}

int getMean(int *p, int size){
	int count = 0;
	for(int i = 0; i < size; i++){
		count += *(p + i);
	}	
	return count / size;
}

int getMedian(int *p, int size){
	bubbleSort(p, size);
	int middle = size / 2;
	if(size % 2 == 0){
		int one = *(p + middle);
		int two = *(p + middle + 1);
		return (one + two) / 2;
	}
	else{
		return *(p + middle);
	}
}

void bubbleSort(int *p, int size){
	for(int i = size; i > 0; i--){
		for(int j = 1; j < i; j++){
			if(*(p + j - 1) > *(p + j)){
				// swap
				int temp = *(p + j - 1);
				*(p + j - 1) = *(p + j);
				*(p + j) = temp;
			}
		}
	}
}

int getMode(int *p, int size){
	// at this time, array has been sorted!
	int countMax = 1, maxVal = *p;
	int tempSum = 0;
	for(int i = 1; i < size; i++){
		if(*(p + i) == *(p + i - 1)){
			tempSum++;
		}
		else {
			tempSum = 0;
		}
		if(tempSum > countMax){
			countMax = tempSum;
			maxVal = *(p + i); 
		}
	}
	
	return maxVal;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值