设计需求:
1.对数据给出区间宽度进行统计 2.生成生成指定区间宽度的直方图绘制数据
设计思路
对直方图的理解:直方图是数值数据分布的精确图形表示,建直方图第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。 这些值通常被指定为连续的,不重叠的变量间隔。 间隔必须相邻,并且通常是(但不是必须的)相等的大小。也可以理解为各区间的相对频率。从数据中求出最大值和最小值,对最大值向上取整,对最小值向下取整,即可得出区间范围。从命令行参数中获得区间值,用区间范围除以区间值可以得到需要多少个区间,把区间长度定义成数组的长度,用数据减去最小值得到的差再除以区间值,就可以得到这个值除于哪个区间,再将所定义数组的相应区间值加一即可。即完成区间内的统计。再把数组的值对应写入到文件中,得到直方图所需的数据。
需要统计的数据
需要统计的数据是8000行服从正态分布其均值为1.2,方差为2.5的数据。
源代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main(int argc
,char* argv
[])
{
int len
= 0, z
;
double data
= 0;
double max
= 0;
double min
= 0;
int num
=0;
if (argc
!= 4)
{
printf("用法:程序名 统计步长 输入文件 输出文件\n");
printf("程序名:编译后后的.exe名称\n");
printf("统计步长:以多大范围统计数据\n");
printf("输入文件:需要统计的文件名\n");
printf("输出文件:数据输出的文件名\n");
return -1;
}
FILE
* fin
= fopen(argv
[2], "r");
FILE
* fout
= fopen(argv
[3], "w");
if (fin
== NULL)
{
printf("源文件打开失败!\n");
return -1;
}
while ((z
= fgetc(fin
)) != EOF)
if (z
== '\n')
{
len
++;
}
rewind(fin
);
char* str
= (char*)malloc(sizeof(char) * len
);
while (1)
{
fscanf(fin
, "%s", str
);
if (feof(fin
)) break;
data
= atof(str
);
if (data
> max
)
{
max
= data
;
}
if (data
< min
)
{
min
= data
;
}
}
rewind(fin
);
double MAX
= ceil(max
);
double MIN
= floor(min
);
double area
= MAX
- MIN
;
double step
= atoi(argv
[1]);
num
= ceil(area
/ step
);
int j
= 0;
int p
= (int)num
;
double a
[p
];
printf("最大值:%lf\n", max
);
printf("最小值:%lf\n", min
);
printf("区间最大值:%.0f\n", MAX
);
printf("区间最小值:%.0f\n", MIN
);
printf("需要%d个区间\n", num
);
for(int i
= 0; i
< p
; i
++)
{
a
[i
] = 0;
}
while (1)
{
fscanf(fin
, "%s", str
);
if (feof(fin
)) break;
data
= atof(str
);
j
= (int)floor((data
- MIN
) / step
);
a
[j
]++;
}
for(int i
=1; i
< p
; i
++)
{
fprintf(fout
, "%.0f %.0f\n", MIN
, a
[i
-1]);
MIN
++;
}
fclose(fin
);
fclose(fout
);
free(str
);
return 0;
}
在gcc中编译并输入命令行指令运行程序 我们打开out.txt 得到统计的数据,在MATLAB中进行验证,交可以看到数据的统计是正确的。