之前曾问过类似的问题,但我的使用方式却未得到回答。
我有3、4、5和6个小组,每个小组应该有50%的男孩和50%的女孩。用户确定每个组的数量以及男孩和女孩的数量。
例如:12个女孩,15个男孩,1 * 3、2 * 4、2 * 5和1 * 6组。
我已经有一个Random
的实例。我现在如何才能将随机选择的男孩/女孩平等地分组?
男孩和4人一组的随机活动:
//for each group of 4
for (int i = 0; i < tischgruppenVierer; i++)
{
//only do this two times because 50% boys
for (int j = 0; j < 4/2; j++)
{
var picked = namesBoys[random.Next(0, namesBoys.Count())];
namesBoys.Remove(picked); //no duplicates
picked = new TischVier().student;
}
}
和类TischVier
:
public class TischVier
{
public string student;
}
我希望这对您来说是足够的代码,因为我对每个组都进行了硬编码。
我感谢每一个想法,因为我快要绝望了。
答案 0 :(得分:1)
有关更多信息,请参见代码中的注释:
//setup
//hold the group sizes we want to make - you say your user chose this
int[] groupSizes = new[] {3, 4, 4, 5, 5, 6};
//you have lists of people from somewhere
List<Person> boys = new List<Person>();
for(int i = 0; i < 15; i++)
boys.Add(new Person());
List<Person> girls = new List<Person>();
for(int i = 0; i < 12; i++)
girls.Add(new Person());
//logic of random grouping
List<List<Person>> groups = new List<List<Person>>();
Random r = new Random();
bool takeBoy = false;
//for each groupsize we make
foreach(int g in groupSizes){
List<Person> group = new List<Person>(); //new group
for(int i = 0; i < g; i++){ //take people, up to group size
//take boys and girls alternately
takeBoy = !takeBoy;
var fr = takeBoy ? boys : girls;
//if there are no more boys/girls, take other gender instead
if(fr.Count == 0)
fr = takeBoy ? girls : boys;
//choose a person at random, less than list length
var ri = r.Next(fr.Count);
//add to the current grouping
group.Add(fr[ri]);
//remove from consideration
fr.RemoveAt(ri);
}
//group is made, store in the groups list
groups.Add(group);
}
演示小提琴:https://dotnetfiddle.net/KS7HFb使用“始终以男孩为先”的逻辑
另一个演示小提琴:https://dotnetfiddle.net/68YFYf使用“全球替代男孩/女孩上瘾”逻辑
答案 1 :(得分:1)
我会将其包装在包含您的2个列表(男孩和女孩)以及用于获取指定大小的组的方法的类中。在伪代码中,此方法为:
在真实代码中,看起来像这样:
public IEnumerable<string> GetGroup(int size)
{
Shuffle(boys);
Shuffle(girls);
if((boys.Count + girls.Count) < size)
{
throw new ArgumentException("Not enough people to satisfy group");
}
bool isBoy = rng.NextDouble() > 0.5;
for(var i = 0;i<size;i++)
{
string next = "";
if(isBoy)
{
yield return PopBoy();
}
else
{
yield return PopGirl();
}
isBoy = !isBoy;
}
}
要使所有这些工作正常进行,您需要检查两个列表中是否有所需组的足够容量(请参阅上面引发的异常)。
存在额外的复杂性;也许男孩或女孩的名单已用尽。在这种情况下,您应该弹出另一个。
private string PopBoy()
{
if(boys.Count>0)
{
var name = boys[0];
boys.RemoveAt(0);
return name;
}
else
{
return PopGirl();
}
}
private string PopGirl()
{
if(girls.Count>0)
{
var name = girls[0];
girls.RemoveAt(0);
return name;
}
else
{
return PopBoy();
}
}
完整的工作代码可以在这里找到:https://rextester.com/DKYCMN49734