【问题标题】:Recursion inside foreach loopforeach循环内的递归
【发布时间】:2021-10-20 12:50:45
【问题描述】:

我在循环中有重复 - 当isAllowed = true - 然后继续下一次迭代,但当 isAllowed 为假时 - 然后程序应该重复生成随机位置、坐标并检查 isAllowed 是否为真。

如何在该循环中进行递归以实现此目标?

foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
    var randomPositionX = new Random().Next(0, 9);
    var randomPositionY = new Random().Next(0, 9);

    var cords = int.Parse(randomPositionX.ToString() + randomPositionY);
    map.Location[cords].ActualFleetPosition = fleet.Key[i];
    var isAllowed = IsPositionAllowed(map, cords);
    if (isAllowed)
    {
        break;
    }
    else
    {
        randomPositionX = new Random().Next(0, 9);
        randomPositionY = new Random().Next(0, 9);

        cords = int.Parse(randomPositionX.ToString() + randomPositionY);
        map.Location[cords].ActualFleetPosition = fleet.Key[i];
        isAllowed = IsPositionAllowed(map, cords);
        if (isAllowed)
        {
            break;
        }
        else
        {
            //recursion
        }
    }
    i++;
}

【问题讨论】:

  • var randomPositionX = new Random().Next(0, 9); var randomPositionY = new Random().Next(0, 9); 不要这样做,将范围之外的随机数声明为静态(类级别),然后在调用代码中使用它们。
  • 我建议您在想要进行下一次迭代时使用 simple for 并移动/增加迭代器/索引器,除非它自动重复循环。
  • 您不应在循环中创建新的 Random 实例 - 您也不需要不同的实例来生成 2 个值。

标签: c# .net for-loop recursion


【解决方案1】:

我想这应该可以解决问题(用你的一些 cmets 编辑,我不想输入其他内容而不是问题):

var random = new Random();    
foreach (var fleet in groupedFleetsbySpaceshipCounts)
    {
        do
        {
            var randomPositionX = random.Next(0, 9);
            var randomPositionY = random.Next(0, 9);

            //Im not sure how you're managing this 'coords' map, but gonna just go to the point 
            var cords = int.Parse(randomPositionX.ToString() + randomPositionY);
            map.Location[cords].ActualFleetPosition = fleet.Key[i];
        } while (!IsPositionAllowed(map, cords));
        i++;
    }

如果您希望 'cords' 变量在 do...while 循环之外可用,您可以在循环之外安全地声明它(更好的是,在 foreach 之外)。

【讨论】:

  • 你确定吗? - cords 变量在范围内,所以它在 do while 中的 {} 之外未定义
  • 您的解决方案作为基础 - 谢谢! - 需要定义上一层的绳索。
【解决方案2】:

也许你想要这样的东西:

var random = new Random();
foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
    int coords;
    do {
        int randomPositionX = random.Next(0, 9);
        int randomPositionY = random.Next(0, 9);

        coords = 10 * randomPositionX + randomPositionY;
    } while (!IsPositionAllowed(map, coords));

    map.Location[coords].ActualFleetPosition = fleet.Key[i++];
}

也就是说,您不需要递归(即调用自身的方法),而是嵌套在第一个循环中的另一个循环。

注意random.Next 的最大值是独占的。因此,如果您想要最大为9 的数字,则必须使用10 的上限值。另外,如果较低的值是0,你可以直接写random.Next(10)

只创建一次Random 对象很重要,否则您最终可能会使用不同的随机对象生成相同的伪随机序列。在类中使用静态字段甚至比使用局部变量更好

private static readonly _random = new Random();

【讨论】:

  • 是的 - 正是 - 它解决了问题 - 一些语法改进,它会工作
  • 但是为什么这里是 operation = 10 * randompositionX + randomPositionY?这里的意图 - concat as string
  • 例如,如果 a = 5 和 b = 7 - 那么线数应该是 57,但这并不重要 - 坐标应该在 0 到 99 之间
  • 嗯,10 * 5 + 7 = 57。不是吗?如果您的坐标高达 99,则使用 100 * x + y (= 507)。但是,您可以改用二维数组:T[,] a = new T[With, Height]; 并使用a[x, y] 访问它。那会更容易。
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 2012-07-19
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
相关资源
最近更新 更多