微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

取一组数字,平均分成3组

如何解决取一组数字,平均分成3组

更详细的解释。我需要取一堆数字并将它们放在班级/组中。假设我有 100 个号码。我需要将其除以类数 (n),其中 n = 3,并将它们分为三组,分别为 33、33、34 个数字。或者如果 (n) = 4,那么它将是 25、25、25、25 的 4 个类别。它们也需要保持从最高到最低的分组。

我已经搜索并看到了一些与 LINQ 相关的内容来执行此操作,但我还没有完全了解它。

我想我可以把所有的数字放在一个列表中,然后找到索引中的总数除以类的数量,以找出每个类需要多少。我的问题是如何从列表中提取数字并将它们放在各自的组中,同时保持从高到低的分组。 3 个班级的 15 个数字所需的结果。

 List<int> test = new List<int> { 100,99,98,97,96,95,94,93,92,91,90,89,88,87,86 };
        int total_indexes = test.Count + 1;
        float classes = (total_indexes / 3);

类等于 5,所以它看起来像下面这样

A 类: 100 99 98 97 96

B 类: 95 94 93 92 91

C 类: 90 89 88 87 86

解决方法

这个解决方案可能不是很优化,有可能会改进。

        int groupNb = 3,elementNb = 100;

        //Populating elements with pseudo-random numbers for demonstration  
        Random r = new Random();
        List<int> elements = new List<int>();
        for (int i = 0; i < elementNb; i++)
            elements.Add(r.Next(0,100));

        //The groups
        List<int>[] groups = new List<int>[groupNb];

        //Classifying elements in groups             
        int currentGroup = 0;
        foreach (int value in elements.OrderByDescending(x => x))
        {
            if (groups[currentGroup] == null)
                groups[currentGroup] = new List<int>();

            groups[currentGroup].Add(value);
            currentGroup = ++currentGroup % groupNb;
        }
,

好的,所以我写了这段代码来给你你想要的结果:

public List<int[]> Do(int[] numbers,int groupCount)
    {
        numbers = numbers.OrderByDescending(x => x).ToArray();

        var result = new List<int[]>();

        var itemsCountInEachGroup = numbers.Length / groupCount;
        var remainingCount = numbers.Length % groupCount;

        var iterateCount = groupCount;
        for (int i = 0; i < iterateCount; i++)
        {
            var skip = i * itemsCountInEachGroup;
            //Last iterate
            if (i == iterateCount - 1)
            {
                var n = numbers.Skip(skip).Take(itemsCountInEachGroup + remainingCount).ToArray();
                result.Add(n);
            }
            else
            {
                var n = numbers.Skip(skip).Take(itemsCountInEachGroup).ToArray();
                result.Add(n);
            }
        }

        return result;
    }

示例 =>

var numbers = new[] { 1,2,3,4,5,6,7,8,9,10,11,12,13 };
var res = Do(numbers,5);
,

我是用 PowerShell 回答的 打开 PowerShell ISE 并编写以下脚本:

$Numbers = 100,94,91,90,89,85,84,81,79,74,70,95,92,83
$SortedNumbers = $Numbers | sort -Descending
$NumberofClasses = 3
$Countofnumbersinclase = $Numbers.Count / $NumberofClasses
$x = 0
$y = 0
For ($i = 0 ; $i -lt $NumberofClasses ;$i++){
$y = $i+$Countofnumbersinclase-1+$y
$Clasno = $i+1
Write-host "class No $Clasno is " $SortedNumbers[$X..$Y]
$x = $y+1
}

结果如下:

第 1 类是 100 95 94 92 91 第 2 类是 90 89 85 84 83 第 3 类是 81 79 74 74 70

我认为正是你想要的,你可以添加任何数字或任何类别,它会起作用

,

如果所有组(只有最后一个除外)应该具有相同数量的项目,您可以尝试Linq {{1 }} 后跟 OrderBy

代码:

GroupBy

如果您的 C# 版本没有 using System.Linq; ... private static List<T>[] Classify<T>(List<T> source,int count) where T : IComparable<T> { int size = source.Count / count; return source .OrderBy(item => item) .Select((item,index) => new { item,index }) .GroupBy(pair => Math.Clamp(pair.index / size,count - 1),pair => pair.item) .Select(group => group.ToList()) .ToArray(); } ,您可以将其实现为

Math.Clamp

演示:

private static int Clamp(int value,int min,int max) {
  return value < min ? min :
         value > max ? max :
         value;        
}

结果:

  // Let's split "count" items into "classes" classes
  int count = 10;
  int classes = 4; 

  List<int> demo = Enumerable
    .Range(1,count)
    .ToList();

  var result = Classify(demo,classes);

  string report = string.Join(Environment.NewLine,result
    .Select(list => $"{list.First()} - {list.Last()} ({list.Count} items) : {string.Join(",",list)}")); 

  Console.Write(report);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。