C#编程:质量管理学中直方图算法类代码

昨天刚中期答辩过去,然后今天开始加快进度进行程序编写了,而论文中的算法目前只写到了直方图部分,所以今天就将直方图的算法写成C#的计算机语言方式。但是在这个过程中遇到了很多问题,因为我以前编程几乎不使用类,虽然我知道类很重要,可以简化程序,加快编写效率,和可重复利用等等的优点,但是一直以来我都是直接写在主程序里的,好一点的我会直接在主程序中写个函数,但是一般连函数我都懒得写,这也造成了我的技术一直没有什么好的提高。

今晚我就趁着这次机会练练使用类的方式编写一下关于直方图数据处理的类文件,但是毕竟第一次,遇到了很多的问题,知道现在,有一些问题还是存在的。比如说类中的函数,也就是类中的方法,要使用什么样子的声明,是public还是protected又或者是private?刚开始我一直写的public声明,但是后来觉得外部基本引用不上,所以后来直接改成了private了,不知道这样子做对不对。还有一点就是之前我在类中的每一个方法都会有一个返回值,但是后来写着感觉这样引用好像很麻烦,毕竟这次的直方图数据处理,只需要拿出接过来便可以了,于是我开始取消了所有方法的返回值,改为了无返回值的方法,并在类中定义了多个属性,这些属性就是本次直方图数据处理中所需要的最终数据。

但是这里又遇到了问题,如果我在程序中实例化了类,那么这些函数依旧是要一个一个的调用的,因此我后来想用构造函数来在调用的时候直接就通过构造函数调用所有的处理函数并令属性获取直方图需要的值,但是在写的过程中,我又犯了一个小错误,就是我发现了构造函数不起效果了,在实例的时候,本来该有的两个构造函数的参数不适用也可以实例化。后来很是郁闷,经过几次的检查才发现,原来构造函数不需要定义返回值类型,连void也不需要,使用了就是错误的了,使用void的话这个就变成了方法而不是构造函数了。

最终,经过一个下午的艰苦奋斗,终于将这直方图的数据处理方法给搞定了。不是很优化的类,不过,的确能够完成直方图数据的处理工作。

其中还有一点就是直方图数据的处理中,按照《质量管理学》中的计算公式,我测试了一下,使用课文中的样本数据和组数进行测试。最终发现如果使用课文中的简化公式求出来的值与原公式所求出的值相差比较大。刚开始我还以为是我编写计算方式错误了,后来经过两种公式的测试,终于发现并不是这样的,而是因为在两种不同公式下计算出现了误差的缘故,因此我将两种公式的计算方法都编写在类中了,并赋给不同的属性中,方便以后使用的选择。
 C#编程:质量管理学中直方图算法类代码

以下是本次编写的直方图数据处理的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace onlineSPC
{
class ValueClass
{
public float[] xarr; //传入的样本数据数组
public float xmax = 0; //数组中的最大值
public float xmin = 0; //数组中的最小值
public float diff = 0; //最大值与最小值的差
public int group = 0; //样本数据分组数
public float[] limitnum; //限制界限,比数组数量大1
public int h = 0; //组距
float simplex = 0; //频数最大的组的中心值
public float[] cennum; //中心值数组,和数组数量相同
public int[] fnum; //频数数组,和数组数量相同
public float[] unum; //简化中心值,和数组数量相同
public float xave = 0; //样本数据平均数
public float snum; //标准偏差
public float xx = 0; //简化公式所求样本平均值
public float xs = 0; //简化公式所求样本标准偏差
public ValueClass(float[] xvalue, int xgroup) //带两个参数的构造函数,第一个参数是样本数据数组,第二个参数是分组数
{
group = xgroup;
xarr = new float[xvalue.Count()];
xarr = xvalue;
reorderValue();
xMaxMin();
hValue();
limitNum();
cenNum();
fNum();
uNum();
xAverage();
sNum();
xX();
xS();
}
private void reorderValue() //将数组内的数字又小到大排序
{
for (int i = 1; i < xarr.Count(); i++)
{
for (int j = 0; j < i; j++)
{
if (xarr[i] >= xarr[j])
{
}
else if (xarr[i] < xarr[j])
{
float tempxvalue;
tempxvalue = xarr[i];
xarr[i] = xarr[j];
xarr[j] = tempxvalue;
}
}
}
xmax = xarr[xarr.Count() – 1];
xmin = xarr[0];
}
private void xMaxMin() //求得X的最大值与最小值的差
{
diff = xmax – xmin;
}
public void hValue() //获取组距h的值,组距为整数
{
int x = Convert.ToInt32(diff) % Convert.ToInt32(group);
if(x != 0)
{
h = (Convert.ToInt32(diff) / Convert.ToInt32(group)) + 1;
}
else
{
h = Convert.ToInt32(diff) / Convert.ToInt32(group);
}
}
private void limitNum() //求得各组限制界限的函数
{
limitnum = new float[group + 1];
limitnum[0] = xmin – (h / 2);
for (int i = 1; i < group + 1; i++)
{
limitnum[i] = limitnum[i – 1] + h;
}
}
private void cenNum() //求得中心值的函数
{
cennum = new float[group];
for(int i = 0; i < group; i++)
{
cennum[i] = (limitnum[i + 1] + limitnum[i]) / 2;
}
}
private void fNum() //求得每组频数的函数
{
fnum = new int[group];
int o = 0; //第o组频数
for (int i = 0; i < xarr.Count(); i++)
{
if(xarr[i] <= limitnum[o + 1])
{
fnum[o]++;
}
else
{
o++;
fnum[o]++;
}
}
}
private void uNum() //求得每组的简化中心值函数
{
int o = 0; //
for (int i = 1; i < group; i++)
{
if (fnum[o] > fnum[i])
{
}
else
{
o = i;
}
}
simplex = cennum[o];
unum = new float[group];
for(int i = 0; i < group; i++)
{
unum[i] = (cennum[i] – simplex) / h;
}
}
private void xAverage() //求一组数据的平均数
{
for (int i = 0; i < xarr.Count(); i++)
{
xave += xarr[i];
}
xave /= xarr.Count();
}
private void xX() //通过简化公式求样本平均值的函数
{
float suma = 0;
float sumb = 0;
for(int i = 0; i < group; i++)
{
suma += (fnum[i] * unum[i]);
sumb += fnum[i];
}
xx = simplex + h * (suma / sumb);
}
private void sNum() //通过标准公式求标准偏差的函数
{
double sumxx = 0;
for(int i = 0; i < xarr.Count(); i++)
{
sumxx = Math.Pow(xarr[i] – xave,2);
}
snum = Convert.ToSingle(Math.Sqrt(sumxx / xarr.Count()));
}
private void xS() //通过简化公式求标准偏差的函数
{
float suma = 0;
float sumb = 0;
float sumc = 0;
for(int i = 0; i < group; i++)
{
suma += (fnum[i] * Convert.ToSingle(Math.Pow(unum[i], 2)));
sumb += (fnum[i] * unum[i]);
sumc += fnum[i];
}
xs = h * Convert.ToSingle(Math.Sqrt((suma / sumc) – Math.Pow((sumb / sumc), 2)));
}
}
}