Итак, вот проблема. Даны 2 целых числа с именами a и b:
// Находим 2 самых больших числа, меньше чем a и b, которые делятся друг на друга.
// ввод: а: 102, б: 53
// вывод: (102,51)
// ввод: а: 7, б: 4
// вывод: (6,3)
// ввод: a: 3, b: 2
// вывод: (2,2)
Загвоздка в том, что я не хочу ее перебирать. Я думаю, что это выходит за O (n²).
Вот подпись для метода:
static Tuple<int, int> Analyze(int a, int b)
{
if (a % b == 0)
return new Tuple<int, int>(a, b);
else
// Here’s where the algorithm kicks in
}
Вот пример реализации:
static Tuple<int, int> Analyze(int left, int right)
{
if (left % right == 0)
return new Tuple<int, int>(left, right);
else
{
for (int i = left; i >= right; i--)
{
for (int j = right; j >= 0; j--)
if (i % j == 0)
return new Tuple<int, int>(i, j);
else
i--;
}
}
return null;
}
Вот тестовый клиент:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Analyze(102, 53));
Console.WriteLine(Analyze(6, 4));
Console.WriteLine(Analyze(3, 2));
}
}
Очевидно, есть проблемы с моей реализацией, но это неплохо для начинающих. Например, когда я использую 106 и 54 для своих аргументов, если бы я не уменьшил переменную внешнего цикла (я - в блоке else), я бы нашел совпадение со 106 и 53. Вместо этого я нахожу совпадение с 52, что не совсем верно, но относительно близко к желаемому результату. Тем не менее, мой пример реализации намного быстрее, чем грубый принудительный подход, потому что я никогда не буду зацикливаться больше, чем b раз, делая его O (b). Мысли, входы?