Элементарные алгоритмы,или шаблоны рассужденийКак известно, многие, причем довольно сложные, алгоритмы можно реализовать,используя некоторое множество стандартных приемов (или их комбинаций). Автор упомянутой выше статьи приводит следующий, довольно полный список несложных и легко запоминаемых правил выбора этих приемов: - если ИХ много, то ЦИКЛ;
- если к моменту обработки ПЕРВОГО известно, сколько ИХ всего, то ЦИКЛ ОТ 1 ДО N;
- если нужно не сбиться со счета, необходима переменная цикла;
- если к моменту обработки ПЕРВОГО неизвестно, сколько ИХ всего, то ЦИКЛ-ДО или ЦИКЛ-ПОКА, в зависимости от того, всегда ли есть ПЕРВЫЙ;
- если ОНИ нужны не раз, то ПОСЛЕДОВАТЕЛЬНОСТЬ (массив, файл, список);
- значение переменной можно использовать, если переменная действительно им обладает;
- если нужно сделать что-то НЕОЧЕВИДНОЕ, то это - ПРОЦЕДУРА;
- если ПРОЦЕДУРА вычисляет что-то одно, то это - ФУНКЦИЯ;
- у процедуры бывают параметры - входные и выходные.
Сразу оговоримся, что под НИМИ подразумевается все, что угодно:элементы данных, выводы на экран букв и/или точек, этапы управления аппаратурой, etc. Структуры данных,или богатство возможностейОднако, использование стандартных алгоритмических приемов, будучи доступно абсолютно всем, не гарантирует эффективного решения ни одной задачи.Очень часто, повышение эффективности (а часто и простоты) программ может быть достигнута за счет использования довольньно простых структур данных и предварительного анализа задачи. Приведем простой пример. Допустим, что требуется вывести на экран некоторое обращение к пользователю на русском языке, причем из некоторых соображений необходимо обращаться к пользователю в определенном роде (и единственном числе).Текст примерно такой "Если бы ты ввел(а)все правильно, то через некоторое время обрадовался(лась) бы результатам работы.".Элементарная программа, выполняющая данные действия с помощью только алгоритмических приемов примерно такова: VarBeginGetSex(B); Write('Если бы ты ввел'); If Not B ThenWriteln(', то ...'); Write('... обрадовал'); If B ThenElseWriteln(' ...'); End. Здесь GetSex - некоторая процедураопределения пола пользователя. В качестве лирического отступления стоит отметить, что переменные, которые по логике программы могут иметь только два значения,и которые будут в будущем анализироваться(а не использоваться, скажем, в формулах),должны иметь логический тип:это ускорит выполнение условных операторов. Однако, те же самые действия можно запрограммировать гораздо проще, понятнее и эффективнее, если применить для хранения окончаний массив: ConstE1: Array [False..True] Of String[1] =E2: Array [False..True] Of String[3] =B: Boolean; BeginGetSex(B); Writeln('Если бы ты ввел'+E1[B]+', то...'); Writeln('... обрадовал'+E2[B]+' бы ...'); End. Как видим, от алгоритма с двумя условными вершинами мы перешли к алгоритму без единой условной вершины, потратив при этом,кстати говоря, около двух лишних байт в сегменте данных (для первой программы константы 'а','ся' и 'ась'тоже присутствуют в сегменте данных).Фактически выигрыш в объеме кода достигается за счет упорядочивания данных в программе. Стоит отметить, что приведенный прием, вообще говоря, не является трюком - мы просто приспособили стандартные механизмы обработки данных (в данном случае - массивов)для решения нашейспецифической задачи. В качестве вывода приведу рекомендации к написанию эффективных программ(для заранее поставленных задач): - проанализировать поставленную задачу (посмотреть на что уже известное она похожа, и нет ли для этого простого и приспособляемого решения. Данное действие требует довольно развитого абстрактного и ассоциативного мышления, а также эрудиции;
- всегда помнить. что для реализации одной и той же задачи существует много алгоритмов. Считать, что самый лучший пришел к вам в голову первым - проявление безграмотности;
- для каждого из способов решения некоторого типа задач (или данной)определить все преимущества и недостатки (сложность реализации,среднее время работы, объем необходимых данных) и основываясь на них выбрать нужный алгоритм. Это, пожалуй, наиболее сложный этап в программировании;
- выявить данные, необходимые для решения задачи, подобрать их тип и структурировать их наиболее удобным для обработки способом. Здесь потребуется глубокое знание механизмов выполнения различных действий в данном ЯП;
- модифицировать изначальный алгоритм с целью переложить как можно большее количество действий на стандартные механизмы языка.
Все просто: хорошо выучи правила и приемы игры и применяй их целенаправленно в нужной последовательности.
|