C# - 递归访问List<>的子部分

时间:2015-12-02 22:56:51

标签: c# list recursion

我正在开发一个作为停车场模拟器运行的程序。要做到这一点,我有:

一个名为ParkingSpace

的班级

A List<ParkingSpace>

一个名为Level的类(包含List<ParkingSpace>作为属性)

A List<Level>

List<ParkingSpace>列表中的空格数是通过用户输入决定的。一旦将所有ParkingSpace实例添加到列表中,我想将它们均匀地分布在多个级别上(即,如果有30个空格和3个级别,则向{{1}添加10个空格每个List<ParkingSpace>实例的属性。

考虑到这个例子,我试图让前10个空格进入第一级,中间10个空格进入第二级,最后10个空格进入第三级。 我尝试使用Level循环和for方法执行此操作,如下所示:

List<ParkingSpace>.getRange()

我原以为这会很好,但出于某种原因,我继续在//number of spaces to be set on each level //total spaces divided by levels to be spread across int spacesPerLevel = spaces.Count / numLevels; //for as many levels as there are for (int i = 0; i < numLevels; i++) { //level at index holds range //level index multiplied by number of spaces on any one level int listRangeStart = (i * spacesPerLevel); //create sub-collection of spaces to be applied to level ParkingSpaces subSpaces = spaces.getRange(listRangeStart, spacesPerLevel); //add these spaces to level Level level = new Level(subSpaces); //add created level to collection of levels Add(level); //remove these spaces from ParkingSpaces collection once applied to level //try to prevent loose collection of spaces not applied to levels spaces.RemoveRange(listRangeStart, spacesPerLevel); } 方法上获得OutOfRangeException

我已经完成了算法的数学运算,据我所知它应该可以工作。任何人都可以发现任何可能会抛弃它的问题吗? 或者,是否有更简单的方法可以递归地添加主列表的另一个列表?

4 个答案:

答案 0 :(得分:2)

我认为这是因为RemoveRange调用,从而减少了列表的大小,从而减少了错误。要解决此问题,只需将.GetRange的行更改为:

ParkingSpaces subSpaces = spaces.GetRange(0, spacesPerLevel);

您拨打RemoveRange的行:

spaces.RemoveRange(0, spacesPerLevel);

答案 1 :(得分:2)

  

或者,是否有更简单的方法可以递归地添加主列表的另一个列表?

无论如何,你的代码中确实没有任何递归,但这是一个简单的方法:

for(int i=0;i<numLevels;i++)
{
        var skip =i*spacesPerLevel;     
        var subSpaces = spaces.Skip(start).Take(spacesPerLevel);
        var level = new Level(subSpaces);
        Add(level);
}

有效地,您创建的是分页算法,并且由于您正在使用实现List<T>的{​​{1}},因此您可以利用SkipTake方法。

答案 2 :(得分:0)

您正在从集合中删除空格,因此您无法获得所需的范围,因为该范围不再存在,我建议使用队列而不是列表,在您到达时将元素出列每个级别的最大金额。

也是一个很好的锻炼。

foreach (var level in levels) {
    while(spaces.any() && level.spaces.count() <= maxPerLevel) {
        level.spaces.add (spaces.dequeue());
    }
}

你还应该考虑不均衡divisibile数字,如果有人输入3个级别和11个空格怎么办?

答案 3 :(得分:0)

也许你可以试试LINQ方法:

var count = 0;
var spacesPerLevel = spaces.Count / numLevels;
var levels = spaces
               .GroupBy(t => count++ / spacesPerLevel)
               .Select(t => new Level(new ParkingSpaces(t.ToList())))
               .ToList();
AddRange(levels);

当然,有一些事情需要注意。您的Level构造函数必须将ParkingSpaces作为参数,而ParkingSpaces类构造函数必须将en IEnumerable<ParkingSpace>作为参数。 LINQ表达式将返回List<Level>,您可以在AddRange方法中使用它来一次添加所有级别。