RRRRR - 54.167.149.128

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

Скрыть / Показать Сортировать по дате
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;

    }

}


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



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

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

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


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


Далее...


Уважаемые Коллеги!

Если Вам нравится наш Форум, Вы можете поддержать его, отправив любую сумму (тогда выберите опцию "Спасибо за Форум").

Вы также можете поддержать конкретное обсуждение и получить гарантированный ответ от наших специалистов (тогда выберите опцию "Прошу эксперта ответить в этой теме").
Задайте Ваш вопрос здесь.

Большое Спасибо!


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