本文章源于我练习中的摸索 可能可以供和我一样的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的值是否相同 判断 有几个众数。
众数的问题就这样解决啦
当然没有遍历那样简单 但思路比较清晰 优化的地方也有很多就是了。
这是博主第一次真正意义上的写一篇博客 有许多地方可能不正确 或不周到
希望大家可以多多包涵 评论建议呀。