12,13,14,15,16,19,19,19,19
to
12,19,13,19,14,19,15,19,16
大家好。谁能为我提供一些线索/示例,以了解如何分配第一个Int32值数组(附加一堆19个值)和第二个数组(其中19个值相当均匀地散布在数组中)?之后,将附加十二个7个值,并且它们也必须均匀分布。我以为Math.NET库中可能有某些东西可以做到这一点,但是我什么也没找到。在.NET Framework 4.7上使用C#。
谢谢。
这里是做得很好的方法。
var existing = new[] { 12, 13, 14, 15, 16 };
var additional = new [] { 19, 19, 19, 19 };
var rnd = new Random();
var lookup = additional.ToLookup(x => rnd.Next(existing.Length));
var inserted =
existing
.SelectMany((x, n) => lookup[n].StartWith(x))
.ToArray();
这给了我类似12, 19, 19, 13, 14, 19, 15, 19, 16
的结果。
这唯一不会做的就是在第一个位置插入一个值,但是否则它会相当均匀地分配这些值。
有关以下方法的详细信息,该方法将均匀(大部分)分布在列表中。重复项可以在列表中的任何位置,它们将被分发。
public static List<int> EvenlyDistribute(List<int> list)
{
int totalLength = list.Count;
Dictionary<int, int> dict = new Dictionary<int, int>();
list.ForEach(x => dict[x] = dict.Keys.Contains(x) ? dict[x] + 1 : 1);
List<int> listWithoutDuplicates = list.Where(x => dict[x] == 1).ToList();
foreach (int key in dict.Keys)
{
if (dict[key] > 1)
{
int iterations = list.Where(x => x == key).Count();
int places = (int)Math.Ceiling((decimal)((listWithoutDuplicates.Count + iterations) / iterations));
for (int i = 0; i < iterations; i++)
listWithoutDuplicates.Insert(places * i, key);
}
}
return listWithoutDuplicates;
}
主要用途:
List<int> test = new List<int>() {11,11,11,13,14,15,16,17,18,19,19,19,19};
List<int> newList = EvenlyDistribute(test);
如果随机分布足够,则下面的代码就足够了:
static void MixArray<T>(T[] array)
{
Random random = new Random();
int n = array.Length;
while (n > 1)
{
n--;
int k = random.Next(n + 1);
T value = array[k];
array[k] = array[n];
array[n] = value;
}
}
例如:
int[] input = new int[]{12,13,14,15,16,19,19,19,19};
MixArray<int>(input);
但是,如果您需要精确地平均分配给以下代码,则可以完成此工作:
public static T[] EvenlyDistribute<T>(T[] existing, T[] additional)
{
if (additional.Length == 0)
return existing;
T[] result = new T[existing.Length + additional.Length];
List<int> distribution = new List<int>(additional.Length);
double ratio = (double)(result.Length-1) / (additional.Length);
double correction = -1;
if (additional.Length == 1)
{
ratio = (double)result.Length / 2;
correction = 0;
}
double sum = 0;
for (int i = 0; i < additional.Length; i++)
{
sum += ratio;
distribution.Add(Math.Max(0, (int)(sum+correction)));
}
int existing_added = 0;
int additional_added = 0;
for (int i = 0; i < result.Length; i++)
{
if (additional_added == additional.Length)
result[i] = existing[existing_added++];
else
if (existing_added == existing.Length)
result[i] = additional[additional_added++];
else
{
if (distribution[additional_added] <= i)
result[i] = additional[additional_added++];
else
result[i] = existing[existing_added++];
}
}
return result;
}
例如:
int[] existing = new int[] { 12, 13, 14, 15, 16};
int[] additional = new int[] { 19, 19, 19, 19};
int[] result = EvenlyDistribute<int>(existing, additional);
//result = 12, 19, 13, 19, 14, 19, 15, 19, 16