Шаг 1: Домашнее хозяйство
Давайте начнем с домашнего хозяйства. Вот тот же код, который вы выложили, но я дал переменные описательные имена и отформатировал код для удобства чтения:
using System;
namespace Double_Egg
{
class Program
{
static int floor = 1;
static int changeFloorResult = 0;
static int changeEggResult = 0;
static int bestChangeResult = 0;
static int bestResult = 0;
static int minFloor;
static int RunDropEggAlgorithm( int numberOfFloors, int numberOfEggs )
{
if( numberOfFloors == 1)
{
return 1;
}
else
{
if( numberOfEggs == 1 )
{
return numberOfFloors;
}
else
{
bestResult = Math.Max( RunDropEggAlgorithm( 1, numberOfEggs - 1 ), RunDropEggAlgorithm( numberOfFloors - 1, numberOfEggs ) );
minFloor = 1;
for( floor = 2; floor <= numberOfFloors; floor++ )
{
changeFloorResult = RunDropEggAlgorithm( floor, numberOfEggs - 1 );
changeEggResult = RunDropEggAlgorithm( numberOfFloors - floor, numberOfEggs );
bestChangeResult = Math.Max( changeFloorResult, changeEggResult );
if( bestChangeResult < bestResult )
{
bestResult = bestChangeResult;
minFloor = floor;
}
}
return Math.Max(
RunDropEggAlgorithm( minFloor, numberOfEggs - 1 ),
RunDropEggAlgorithm( numberOfFloors - minFloor, numberOfEggs )
) + 1;
}
}
}
static void Main( string[] args )
{
int numberOfFloors = 1;
int numberOfEggs = 1;
int result = 1;
Console.Write("Please enter number of Floors:");
numberOfFloors = int.Parse( Console.ReadLine() );
Console.Write("Please enter numer of eggs:");
numberOfEggs = int.Parse( Console.ReadLine() );
result = RunDropEggAlgorithm( numberOfFloors, numberOfEggs );
Console.WriteLine("The minimum number of throwing test is:" + result);
}
}
}
Шаг 2: Отладка
Теперь, когда мы знаем, что для каждой переменной на самом деле представляет, давайте посмотрим, что вызывает ошибку переполнения стека:
При работе с рекурсивными алгоритмами переполнение стека происходит, когда не проверяется какой-либо базовый случай или граничное условие (например, не учитываются оба n == 0
и n == 1
при реализации генератора серии Фибоначчи.
Когда я вставляю код в DotNetFiddle , запускаю его и поставляю floors: 2, eggs: 2
Я получаю исключение тайм-аута (это потому, что DotNetFiddle завершает работу программы до того, как StackOverflowException
может произойти) - но этого все же достаточно, чтобы выявить проблему с помощью визуального осмотра (у меня в любом случае на моем текущем компьютере нет пошагового отладчика C#).
Быстрый и грязный способ отладки состоит в том, чтобы печатать аргументы параметра RunDropEggAlgorithm
каждый раз, когда вводится метод:
[...]
static int RunDropEggAlgorithm( int numberOfFloors, int numberOfEggs )
{
Console.WriteLine( nameof(RunDropEggAlgorithm) + " numberOfFloors: {0}, numberOfEggs: {1}. Press [Enter] to continue...", numberOfFloors, numberOfEggs );
Console.ReadLine();
if( numberOfFloors == 1)
[...]
Таким образом, мы получаем этот вывод, когда запускаем его с тем же входом:
Please enter number of Floors:2
Please enter numer of eggs:2
RunDropEggAlgorithm numberOfFloors: 2, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 1
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 2, numberOfEggs: 1
RunDropEggAlgorithm numberOfFloors: 0, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 1
RunDropEggAlgorithm numberOfFloors: -1, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 1
>
Даже без просмотра видео, на которое вы ссылались, я подозреваю, что numberOfFloors
НЕ должно быть -1
, так что если изменить первые два if
оператора RunDropEggAlgorithm
с == 1
на <= 1
примерно так ...:
[...]
static int RunDropEggAlgorithm( int numberOfFloors, int numberOfEggs )
{
Console.WriteLine( nameof(RunDropEggAlgorithm) + " numberOfFloors: {0}, numberOfEggs: {1} Press [Enter] to continue...", numberOfFloors, numberOfEggs );
Console.ReadLine();
if( numberOfFloors <= 1)
{
return 1;
}
else
{
if( numberOfEggs <= 1 )
{
return numberOfFloors;
}
[...]
... тогда я получу этот вывод, который я Предположим, это правильно:
Please enter number of Floors:2
Please enter numer of eggs:2
RunDropEggAlgorithm numberOfFloors: 2, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 1
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 2, numberOfEggs: 1
RunDropEggAlgorithm numberOfFloors: 0, numberOfEggs: 2
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 1
RunDropEggAlgorithm numberOfFloors: 1, numberOfEggs: 2
The minimum number of throwing test is:2