9737
СОГЛАСЕН С ОБРАБОТКОЙ ЛИЧНЫХ ДАННЫХ

Обсуждения-аналоги

Скрыть / Показать Сортировать по дате
2010-01-22 14:59:57
Сычев С.В., Лебедев К.А. » Всем

2. ПЕРЕБИРАЯ ВАРИАНТЫ

Предположим, необходимо написать несложный интерпретатор арифметических выражений. Выражения могут содержать 4 арифметические операции: +, -, *, /

Например:


3 + 5

12 - 4

3 * 2

6 / 2


Кроме того, допустимы выражения, которые содержат несколько операций, и выражения со скобками.

Например:


5 * 2 - 3

(3 + 2) * 3


Казалось бы, "тоже мне задача". Но предлагая ее даже "продвинутым студентам" (сказать по правде, даже и еще более продвинутым Коллегам), мы столкнулись со следующим: редко кто пытается представить даже маленький проект сразу в целом. Наоборот, большинство ответов представляют собой попытки сходу написать "работающий частный случай", с тем чтобы уже затем "по мере поступления" поддерживать сложные выражения.

Хорошо ли это? Может быть, так и надо? Давайте посмотрим.


Вот пример очень характерного ответа (далее цитирование):

"Если выражение состоит из одной операции и двух операндов, то алгоритм интерпретации такого выражения выглядит достаточно просто:

  1. Считать первый операнд и поместить его в массив операндов.
  2. Считать знак операции и занести его во внутреннюю переменную.
  3. Считать второй операнд и поместить его в массив операндов.
  4. Посчитать результат выражения.

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


На языке программирования C++ алгоритм интерпретатора арифметических выражений выглядел бы таким образом (без кода обработки ошибок):

 

double fltResult;

double Operands[2];

int iOperand = 0;

char chOp = '0';

TToken token;

 

while (GetToken(&token))

{

    switch (token.GetType())

    {

        case eTokenOperand: //Операнд

            Operands[iOperand++] = token.GetOperand();

            break;

        case eTokenOperation: //Операция

            chOp = token.GetOperation();

            break;

        case eTokenCalculation:

            {

                switch (chOp)

                {

                    case '+': //Плюс

                        fltResult = Operands[0] + Operands[1];

                        break;

                    case '-': //Минус

                        fltResult = Operands[0] - Operands[1];

                       break;

                    case '*': //Умножить

                        fltResult = Operands[0] * Operands[1];

                        break;

                    case '/': //Разделить

                        fltResult = Operands[0] / Operands[1];

                        break;

                }

            }

            break;

    }

}


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



Сравним приведённое решение с первоначальными требованиями. Можно ли считать, что решение им удовлетворяет? На первый взгляд, "и нет, и да".

  • Нет. Т.к. в требованиях говорится о поддержке выражений с несколькими операциями, а предложенное решение поддерживает выражения только с одной операцией. 
  • Может быть, и да. Т.к. видно из решения, что иные операции будут поддерживаться по аналогии. Кроме того, программист, предложивший решение, верит в то, что найдет позже приемлемые варианты для конструирования более сложных комбинаций.
  • Нет. Т.к. в требованиях подчёркивается необходимость поддержки выражений со скобками, а предложенное решение поддерживает выражения без скобок.
  • Может быть, и да. Т.к. программист, похоже, не видит противоречий, которые возникнут при развитии проекта предложенным способом.

Фраза "может быть" здесь ключевая. Т.к., волей-неволей, предложенным решением заложена определенная (назовем ее "портяночная") идеология развития проекта. Между тем, для целей качественного проектирования было бы здорово сразу попытаться увидеть "идеальный образ" - т.е. полное и компактное решение задачи (не требующее дальнейших дописок, комбинаций, поправок, деревьев и хитроумных структур).


Однако, возможно ли это?


Далее...




Яндекс.Метрика