namespace IStation
|
{
|
public class ModeHelper
|
{
|
/// <summary>
|
/// 结构:用于统计每个数出现的次数
|
/// </summary>
|
struct Stats
|
{
|
//数字,出现的次数
|
public double Number;
|
public int Count;
|
//构造函数
|
public Stats(double n, int c)
|
{
|
Number = n;
|
Count = c;
|
}
|
}
|
|
/// <summary>
|
/// 计算数组的众数
|
/// </summary>
|
/// <param name="array">数组</param>
|
/// <param name="threshold">数量阈值,众数数量若多于次数则认为没有众数</param>
|
/// <returns></returns>
|
public static double[] ModeOf(double[] array, int threshold = 5)
|
{
|
//数组排序-统计各元素数量-按各元素数量排序-再统计最多的元素
|
//1.输入合法性检验
|
if (array == null || array.Length == 0 || threshold < 1)
|
{
|
return new double[] { };
|
}
|
|
//2.制作数组副本,后面的操作将不修改数组本身
|
double[] tempArray = new double[array.Length];
|
array.CopyTo(tempArray, 0);
|
|
//3.数组排序
|
double temp;
|
for (int i = 0; i < tempArray.Length; i++)
|
{
|
for (int j = i; j < tempArray.Length; j++)
|
{
|
if (tempArray[i] < tempArray[j])
|
{
|
temp = tempArray[i];
|
tempArray[i] = tempArray[j];
|
tempArray[j] = temp;
|
}
|
}
|
}
|
|
//4.统计不同的元素数
|
int counter = 1;
|
for (int i = 1; i < tempArray.Length; i++)
|
{
|
if (tempArray[i] != tempArray[i - 1])
|
{
|
counter++;
|
}
|
}
|
|
//5.统计各个元素数量
|
int flag = 0;
|
Stats[] statsArray = new Stats[counter];
|
statsArray[flag].Number = tempArray[0];
|
statsArray[flag].Count = 1;
|
for (int i = 1; i < tempArray.Length; i++)
|
{
|
if (tempArray[i] == statsArray[flag].Number)
|
{
|
statsArray[flag].Count++;
|
}
|
else
|
{
|
flag++;
|
statsArray[flag].Number = tempArray[i];
|
statsArray[flag].Count = 1;
|
}
|
}
|
|
//6.按元素在原数组内数量(Count属性)降序排列
|
// 数量相等的元素则按大小升序排列
|
for (int i = 0; i < statsArray.Length; i++)
|
{
|
for (int j = i; j < statsArray.Length; j++)
|
{
|
if (statsArray[i].Count < statsArray[j].Count ||
|
(statsArray[i].Count == statsArray[j].Count &&
|
statsArray[i].Number > statsArray[j].Number))
|
{
|
temp = statsArray[i].Number;
|
statsArray[i].Number = statsArray[j].Number;
|
statsArray[j].Number = temp;
|
temp = statsArray[i].Count;
|
statsArray[i].Count = statsArray[j].Count;
|
statsArray[j].Count = (int)temp;
|
}
|
}
|
}
|
|
//7.统计众数数量
|
int count = 1;
|
if (statsArray.Length > threshold &&
|
statsArray[threshold].Count == statsArray[0].Count)
|
{
|
//众数多余阈值数量,则认为没有众数
|
return new double[] { };
|
}
|
else
|
{
|
for (int i = 1; i < statsArray.Length && i < threshold; i++)
|
{
|
if (statsArray[i].Count == statsArray[i - 1].Count)
|
{
|
count++;
|
}
|
else break;
|
}
|
}
|
|
//8.生成返回众数数组
|
double[] result = new double[count];
|
for (int i = 0; i < count; i++)
|
{
|
result[i] = statsArray[i].Number;
|
}
|
return result;
|
}
|
}
|
}
|