在C#中具有均匀分布的Int数组重新排序?

问题描述 投票:0回答:2
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#。

谢谢。

c# linq sorting distribution
2个回答
0
投票

这里是做得很好的方法。

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的结果。

这唯一不会做的就是在第一个位置插入一个值,但是否则它会相当均匀地分配这些值。


0
投票

有关以下方法的详细信息,该方法将均匀(大部分)分布在列表中。重复项可以在列表中的任何位置,它们将被分发。

  1. 创建所有数字的字典并跟踪它们出现在列表中的次数
  2. 使用没有重复的新列表。对于每个具有重复项的数字,将其分布在此新列表的大小上。每次分布均匀。
    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);

-1
投票

如果随机分布足够,则下面的代码就足够了:

    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
© www.soinside.com 2019 - 2024. All rights reserved.