Практика 4.5 — Сравнение соседних значений


Предыдущие значения, соседние тройки и таблицы трассировки

В этих задачах вы будете сравнивать соседние символы и числа. Сохраняйте один или два предыдущих ввода, чтобы проверять пары и тройки, не запоминая всю последовательность.

Упражнение 4.5.1 — Последовательные символы

Напишите программу, которая считывает 30 строчных латинских букв и считает, сколько раз очередная буква следует непосредственно за предыдущей в алфавите. Например, пара c, d подходит, а d, c — нет.

Значения типа char можно сравнивать: C# использует их числовые коды UTF-16. Для латинских букв одного регистра алфавитный порядок соответствует порядку кодов.

Для короткого примера из восьми символов:

t, a, d, c, d, c, s, t

Результат:

2

Подходят соседние пары c, d и s, t. Если запускаете проверку на этом примере, временно измените количество вводов с 30 на 8.

Упражнение 4.5.2 — Локальные вершины

Напишите программу, которая считывает 50 чисел и считает соседние тройки, в которых среднее число больше обоих соседних.

Проверяйте тройки со сдвигом на одно число: после 42, 45, 40 проверяется 45, 40, 80. Тройки могут перекрываться.

Для короткого примера из восьми чисел:

25, 40, 30, 9, 80, 40, 45, 42

Результат:

3

Средние элементы подходящих троек — 40, 80 и 45.

Решение

Сохраняем два предыдущих числа: prevPrev и prev. После нового ввода тройка имеет вид prevPrev, prev, current.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void Main()
{
    int count = 0;
    int prev = 0;
    int prevPrev = 0;

    for (int i = 0; i < 50; i++)
    {
        Console.Write("Введите число: ");
        int current = int.Parse(Console.ReadLine());

        // Первую полную тройку получаем только на третьем вводе.
        if (i > 1 && prev > current && prev > prevPrev)
            count++;

        prevPrev = prev;
        prev = current;
    }

    Console.WriteLine("Количество подходящих троек: " + count);
}

Благодаря условию i > 1 начальные нули не участвуют в сравнении. К моменту первой проверки обе переменные уже содержат настоящие вводы.

Порядок последних двух присваиваний важен: сначала переносим старое prev в prevPrev и только затем заменяем prev текущим числом. Если поменять команды местами, обе переменные будут хранить current.

Для проверки на восьми числах из примера временно замените i < 50 на i < 8.

Упражнение 4.5.3 — Одинаковые края, другая середина

Напишите программу, которая считывает 40 символов и считает соседние тройки, в которых первый и третий символы одинаковы, а средний отличается от них обоих.

Пример из десяти символов:

s, r, t, r, t, a, b, b, b, a

Результат:

2

Подходят перекрывающиеся тройки r, t, r и t, r, t. Тройка b, b, b не подходит, потому что её средний символ не отличается от крайних.

Упражнение 4.5.4 — Сравнение сумм соседних пар

Проследите начало выполнения программы для трёх пар ввода:

  1. (90, 100);
  2. (200, 300);
  3. (150, 100).

Каждое число вводится на отдельной строке. Объясните, когда выводится сообщение «Сумма уменьшилась» и почему предыдущую пару нужно обновлять после сравнения.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void Main()
{
    Console.WriteLine("Введите два целых числа");
    int prev1 = int.Parse(Console.ReadLine());
    int prev2 = int.Parse(Console.ReadLine());

    for (int i = 0; i < 108; i++)
    {
        Console.WriteLine("Введите два целых числа");
        int current1 = int.Parse(Console.ReadLine());
        int current2 = int.Parse(Console.ReadLine());
        if (current1 + current2 < prev1 + prev2)
        {
            Console.WriteLine("Сумма уменьшилась");
        }

        prev1 = current1;
        prev2 = current2;
    }
}

Программа ожидает 109 пар: одну до цикла и ещё 108 внутри. Три заданные пары позволяют проследить только первые два повторения. Чтобы выполнить программу до конца, понадобятся ещё 106 пар; для запуска только этого короткого примера можно временно заменить i < 108 на i < 2.

Решение: трассировка первых двух повторений

До цикла выводится приглашение «Введите два целых числа», затем prev1 получает 90, а prev2100.

В таблице значения предыдущей пары показаны до сравнения с текущей. Перед вводом каждой новой пары программа повторяет приглашение.

i i < 108 prev1 prev2 current1 current2 Условие сравнения сумм Вывод после сравнения
0 true 90 100 200 300 500 < 190false
1 true 200 300 150 100 250 < 500true Сумма уменьшилась

После первого повторения предыдущая пара становится (200, 300), после второго — (150, 100).

Затем i увеличивается до 2, условие 2 < 108 остаётся истинным, и программа снова приглашает ввести пару. По трём данным парам дальнейший результат определить нельзя.

Если не обновлять prev1 и prev2, все новые пары будут сравниваться с самой первой. Если обновить их до условия, сумма текущей пары будет сравниваться с ней самой. Поэтому обновление выполняется после сравнения, перед следующим повторением.

Дальше