Поиск на основе таблицы

Эта статья является первой из серии, посвященной классическому произведению Стива МакКоннелла «Code Complete», посвященному компьютерному программированию и программной инженерии.

МакКоннелл дает всевозможные отличные советы в «Code Complete», но в некоторых из его примеров используются языки, которые больше не популярны, например Visual Basic. В моих статьях примеры будут обновляться за счет использования более популярных языков, таких как JavaScript и Python.

В этой статье будет рассмотрено, как мы можем улучшить наши программы, используя поиск по таблицам, а не длинные серии операторов if-else if.

Решение длинных операторов if-else if

Начнем с проблемы со свиданием. У вас должна быть возможность сопоставить месяц с количеством дней в этом месяце. Ваша первая интуиция состоит в том, чтобы написать длинный if-else if оператор, который присваивает дни конкретному месяцу. Вот как это выглядит в Python:

Это очень длинный ряд утверждений.

При небольшом осмотре вы должны увидеть, что номера месяцев соответствуют индексам массива. Обладая этим пониманием, мы можем создать массив (или список на Python), в котором будут храниться дни каждого месяца, связав дни месяца с правильным индексом массива.

Вот инструкция для создания этого списка:

monthDays = [0,31,28,31,30,31,30,31,31,30,31,30,31]

Обратите внимание, что у нас есть 0 в первом элементе списка, поскольку мы не нумеруем месяцы, начинающиеся с 0. Другой способ сделать это - начать с дней января, а затем вычесть 1 из числа, которое пользователь вводит для месяца. .

Вот полная программа:

monthDays = [0,31,28,31,30,31,30,31,31,30,31,30,31]
month = int(input("What month is it (enter a number: )? "))
days = monthDays[month]
print("Month",month,"has",days,"days in it.")

Мы сократили программу из 26 строк до четырех, что сделало ее более читаемой и эффективной.

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

monthDays = [0,31,28,31,30,31,30,31,31,30,31,30,31]
monthNames = ["", "January", "February", "March", "April",
              "May", "June", "July", "August", "September",
              "October", "November", "December"]
month = int(input("What month is it (enter a number: )? "))
days = monthDays[month]
monthName = monthNames[month]
print(monthNames[month],"has",days,"days in it.")

Давайте рассмотрим еще один способ решения этой проблемы в Python.

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

Вот словарное решение проблемы дней в месяце:

В этих примерах я создал два типа таблиц поиска. Таблица поиска - это структура данных, в которой необходимые данные находятся путем доступа либо к индексу (в случае массива или списка), либо к ключу (в случае словаря).

Пример логической функции

Логическая функция (функция, возвращающая логическое значение) может содержать таблицу поиска и использоваться вместо оператора if-else if. Однако сначала давайте рассмотрим пример, в котором не используется таблица поиска в JavaScript.

Задача просит вас подсчитать количество гласных в строке. У вас может возникнуть соблазн проверить каждый символ строки с помощью оператора if-else if, например:

Но лучший способ - сохранить гласные в массиве, который затем проверяется на предмет наличия в нем указанного символа. Вот один из способов написать программу с использованием логической функции:

Одним из преимуществ этой программы перед предыдущей программой, использующей оператор if-else if, является то, что я использовал встроенную функцию массива JavaScript, includes. Использование встроенной функции более эффективно, чем цикл по массиву для сравнения каждого элемента с заданным символом, что заставило бы меня использовать if-else if в определении функции.

Использование таблицы поиска по ступеням

Другой тип справочной таблицы, которую МакКоннелл демонстрирует в Code Complete, - это справочная таблица для ступенек. Этот тип таблицы используется, когда проблема не может быть решена с помощью «аккуратных» массивов или индексов списка.

Пример, который использует МакКоннелл, - это приложение для выставления оценок, в котором вы должны присвоить буквенную оценку числовому баллу. Если диапазон числовых оценок нерегулярен, обычная таблица поиска не может использоваться.

Пороговые значения для оценок: 50 или ниже F; до 65,0 Д; до 75,0 С; до 90,0 млрд; и до 100,0 А.

Вот программа:

Этот код работает, перебирая диапазон оценок и сравнивая числовой балл учащегося с указанными верхними пределами в массиве gradeRange. Буквенная оценка определяется, когда оценка учащегося превышает верхнюю границу диапазона.

Попытка написать эту программу с использованием if-else if логики сделает код слишком сложным и может привести к логическим ошибкам. Еще одно преимущество использования этого типа таблицы, как и в предыдущих примерах, заключается в том, что использование таблицы поиска упрощает изменение диапазона, если это необходимо.

Преимущества таблиц поиска

Использование таблиц поиска по сравнению с логикой if-else if дает несколько преимуществ.

Во-первых, код, использующий таблицы поиска, легче читать, особенно когда if-else if statement является длинным. Еще одно преимущество состоит в том, что таблицы поиска легче обновлять при изменении логики. Попытка изменить сложное if-else if заявление может привести к ошибкам при внесении изменений.

Как заявляет МакКоннелл, если вы обнаружите, что у вас возникли проблемы с выполнением логики оператора if-else if, подумайте о замене его на таблицу поиска.

Спасибо, что прочитали эту статью. Пожалуйста, напишите мне с комментариями и предложениями.