本文章源于我练习中的摸索 可能可以供和我一样的c语言小白借鉴 

题目 n个数据 求出其平均值Mean 中位数Median 众数Mode


平均值比较容易得到

#include <stdio.h>
#include <stdlib.h>
#define NUM 10

float Mean(int a[], int n)
{
	int i;
	int sum = 0;
	for (i = 0; i < n; i++)
		sum = sum + a[i];
	return ((float)sum / n);
}


int main()
{
	int i;
	int feedback[NUM] = {0};
	for (i = 0; i < NUM; i++)
	{
		printf("请输入第%d个数:", i + 1); scanf("%d", &feedback[i]);
	}
	printf("Mean =%3f\n", Mean(feedback, (sizeof(feedback) / sizeof(feedback[0]))));
	

}

这里是对数组所有元素求平均数

向函数中传输数组 只是传入其首元素地址 所以通过传入第二个参数 n来确定数组的元素个数

n 可以通过sizeof的方式得到


中位数:

#include <stdio.h>
#include <stdlib.h>
int cmpint(const void* x, const void* y)
{
	return (*(int*)x - *(int*)y);
float Median(int a[], int n)
{
	if (n % 2 == 0)
		return((a[n / 2 - 1] + a[n / 2]) / (float)2);
	else
	return(a[n / 2 + 1]);
}
int main()
{
	int i;
	int feedback[NUM] = {0};
	for (i = 0; i < NUM; i++)
	{
		printf("请输入第%d个数:", i + 1); scanf("%d", &feedback[i]);
	}
	qsort(feedback, NUM, sizeof(int), cmpint);
	printf("Median =%3f\n", Median(feedback, (sizeof(feedback) / sizeof(feedback[0]))));
}

这里使用了qsort函数 下面是简单的模板 

void qsort(void *base, size_t nitems, size_t size, int(*compar)(const void *, const void*))
base -- 指向要排序的数组的第一个元素的指针。
nitems -- 由 base 指向的数组中元素的个数。
size -- 数组中每个元素的大小,以字节为单位。
compar -- 用来比较两个元素的函数。
比较函数模板下图有
int cmpfunc(const void * a, const void * b)
{
	return (*(int*)a - *(int*)b);
}

默认是使数组内的元素从小到大排列 这是与此时自己设计的比较函数(cmpfunc)的返回值有关的

如果想令数组内元素从大到小排列 只需更改返回值的正负号即可 后面众数的筛选便利用了这一点。

经过qsort排列的数组是从小到大的 此时很轻易便能找到中位数

当然不要忘记分情况讨论 数组元素是单数还是双数


众数

不知道各位是否和我一样 对于平均数以及中位数的求取是思路很清晰的

但是对于众数的筛选就犯了难

这里我采用的方法可能没有其他博主那么简单 但是绝对易懂

#include <stdio.h>
#include <stdlib.h>
#define NUM 10
struct abc
{
	int num;//4字节
	int sum;//4字节
};
int cmp(const void *a, const void *b)
{
	return (*(struct abc *)b).sum-(*(struct abc *)a).sum ;
//从大到小排列 这里让 b-a 即-(a-b)
}
void Mode(int a[], int n)
{
	struct abc c[NUM];
	int i = 0, j = 0, k = 1,l=0;
	for (i = 0; i < n; i++)
	{
		if (a[i] == a[i + 1])
			k++;
		else
		{
			c[j].num = a[i];
			c[j].sum = k;
			j++;
			k = 1;
		}
	}
	qsort(c, NUM, sizeof(struct abc), cmp);
	i = 0;
	while(c[i].sum == c[i + 1].sum)
		i++;
	printf("mode=");
	for (l = 0; l <=i; l++)
	{
		printf("%d  ", c[l].num);
	}
	printf("\n");
}
		
int main()
{
	int i;
	int feedback[NUM] = {0};
	for (i = 0; i < NUM; i++)
	{
		printf("请输入第%d个数:", i + 1); scanf("%d", &feedback[i]);
	}
Mode(feedback, (sizeof(feedback) / sizeof(feedback[0])));

}

第一次使用qsort将数组内的数 从小到大排列 

然后创建结构体 abc c[NUM] 有两个参数

一是这个数字本身num

二是这个数字出现的次数sum(我当作出现次数之和所以用sum)

此时结构体数组内存储的便是 一个数 与其出现的次数 两个数据

但是此时这个结构体数据排列的顺序 是由 c[ ].num 的大小

数字的大小所决定的 即 由数字的值 从小到大排列

我们想得到众数 即应该让结构体的顺序与 数字的出现次数有关 即 c[ ],sum

那么又用到了qsort函数 同理的用法 不过这里的指针类型也要做相应更改

因为众数应为出现次数最多的数 这里应从大到小排列(因为实际上结构体数组中的所有元素不一定会全用上 等问题)

然后 我们就得到了一个 按数出现次数由高到底排列的结构体数组

那么c[0].num 即是我们想得到的那个众数

当然 此处依然有问题 多个众数 或是不存在众数

这里就可以由数组c[i].sum与c[i+1].sum的值是否相同 判断 有几个众数。

众数的问题就这样解决啦

当然没有遍历那样简单 但思路比较清晰 优化的地方也有很多就是了。


这是博主第一次真正意义上的写一篇博客 有许多地方可能不正确 或不周到

希望大家可以多多包涵 评论建议呀。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐