На нашем сайте мы используем cookie для сбора информации технического характера и обрабатываем IP-адрес вашего местоположения. Продолжая использовать этот сайт, вы даете согласие на использование файлов cookies. Здесь вы можете узнать, как мы пользуемся файлами cookies.
Я согласен
логотип upread.ru

Таблицы поиска для повышения эффективности программирования



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

Решение с операторами if-else if

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

$month = 3;

if ($month == 1)
  $days = 31;
elseif ($month == 2)
  $days = 28;
elseif ($month == 3)
  $days = 31;
elseif ($month == 4)
  $days = 30;
elseif ($month == 5)
  $days = 31;
elseif ($month == 6)
  $days = 30;
elseif ($month == 7)
  $days = 31;
elseif ($month == 8)
  $days = 31;
elseif ($month == 9)
  $days = 30;
elseif ($month == 10)
  $days = 31;
elseif ($month == 11)
  $days = 30;
elseif ($month == 12)
  $days = 31;

echo $days;
Это очень длинная серия операторов.

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

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

$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 = 3;
$days = $monthDays[$month];
echo $days;
Мы сократили 26-строчную программу до четырех строк, сделав ее более читаемой и более эффективной.

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

$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 = 3;
$days = $monthDays[$month];
$monthName = $monthNames[$month];

echo $days." in ".$monthName;


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

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

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

daysInMonth = {
  "January" : 31,
  "February" : 28,
  "March" : 31,
  "April" : 28,
  "May" : 31,
  "June" : 30,
  "July" : 31,
  "August" : 31,
  "September" : 30,
  "October" : 31,
  "November" : 30,
  "December" : 31}
month = input("What month is it? ")
days = daysInMonth[month]
print(month,"has",days,"days in it.")
То, что я создал в этих примерах, - это два типа таблиц поиска. Таблица поиска - это структура данных, в которой необходимые данные можно найти, обратившись либо к индексу (в случае массива или списка), либо к ключу (в случае словаря).

Пример булевой функции

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

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

let sentence = "now is the time for all good people";
let count = 0;
for (let i = 0; i < sentence.length; i++) {
  if (sentence[i] == 'a' || sentence[i] == 'e' ||
      sentence[i] == 'i' || sentence[i] == 'o' ||
      sentence[i] == 'u') {
    count++;
  }
}
console.log("There are " + count + " vowels in the string.");
Но способ лучше - это хранить гласные в массиве, который затем проверяется, есть ли в нем указанный символ. Вот один из способов написания программы с помощью булевой функции:

function isVowel(ch) {
  let vowels = ['a','e','i','o','u'];
  if (vowels.includes(ch)) {
    return true;
  }
  return false;
}
let sentence = "now is the time for all good people";
let count = 0;
for (let i = 0; i < sentence.length; i++) {
  if (isVowel(sentence[i])) {
    count++;
  }
}
console.log("There are " + count + " vowels in the string.");
Одно из преимуществ этой программы по сравнению с предыдущей программой, которая использует оператор if-else if, заключается в том, что я использовал встроенную функцию массива JavaScript, includes. Использование встроенной функции более эффективно, чем перебор массива для сравнения каждого элемента с заданным символом, что заставило бы меня использовать if-else if в определении функции.

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

Другой тип таблицы поиска - это таблица поиска ступеней лестницы. Данный тип таблицы используется, когда проблема не может быть решена с помощью “аккуратных” индексов массива или списка.

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

Отсечки для оценок: 50 или ниже F; до 65,0 D; до 75,0 C; до 90,0 B; и до 100,0 A.

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

let gradeRange = [50.0, 65.0, 75.0, 90.0, 100.0];
let grades = ["F", "D", "C", "B", "A"];
let maxGrade = grades.length - 1;
let studentScore = 68.7;
let gradeLevel = 0;
let studentGrade = "A";
while (studentGrade == "A" && gradeLevel < maxGrade) {
  if (studentScore < gradeRange[gradeLevel]) {
    studentGrade = grades[gradeLevel]
  }
  gradeLevel++;
}
console.log("A score of " + studentScore + " is a letter grade of " +
      studentGrade + ".");
Этот код работает путем циклического перебора диапазона оценок и сравнения числового балла студента с перечисленными верхними пределами в массиве gradeRange. Буквенная оценка определяется, когда оценка студента превышает верхнюю часть диапазона.

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

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

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

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



Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.



тегизаметки, javascript, теория программирования, php, python





Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Урок 10. Перегрузка логического оператора C#
Помощь программиста онлайн


© upread.ru 2013-2022
При перепечатке активная ссылка на сайт обязательна.
Задать вопрос
письмо
Здравствуйте! Вы можете задать мне любой вопрос. Если не получается отправить сообщение через эту форму, то пишите на почу up777up@yandex.ru
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.