9737
@ Подписаться
Сотни бизнес-методик. Тысячи кейсов. Обновления.

сегодня 13843 Подписчиков


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

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

15. И НАДО БЫ УКРОТИТЬ АЛГОРИТМ ИНТЕРПРЕТАЦИИ

Т.о., мы сделали компактную, неменяющуюся "преобразовалку" инфиксного выражения в выражение в формате ПОЛИЗ. Нам осталось упростить алгоритм интерпретации.


Когда внутри него была лишь сущность "операнд" и "четыре действия арифметики", он бы невелик:


std::vector<double> Stack;
TToken token;


while (GetToken(&token))
{
       switch (token.GetType())
       {
              case eTokenOperand:
//Операнд
                     Stack.push_back(token.GetOperand());
                     break;
              case
eTokenPlus: //Плюс
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 + fltArg2);
                     }
                     break;
              case eTokenMinus:
//Минус
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 - fltArg2);
                     }
                     break;
              case eTokenMultiply: //Умножить
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 * fltArg2);
                     }
                     break;
              case eTokenDivide: //Разделить
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 / fltArg2);
                     }
                     break;
       }
}



Теперь же количество case’ов внутри длинного оператора switch выросло на блок "Функция". Было бы только это, смирились бы. Но и внутри нового блока "Функция" возникает "портянка" по числу видов функций, которые должен "понимать" интерпретатор, а число их не ограничено.


std::vector<double> Stack;
TToken token;


while (GetToken(&token))
{
       switch (token.GetType())
       {
              case eTokenOperand:
//Операнд
                     Stack.push_back(token.GetOperand());
                     break;
              case eTokenPlus: //Плюс
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 + fltArg2);
                     }
                     break;
              case eTokenMinus:
//Минус
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 - fltArg2);
                     }
                     break;
              case eTokenMultiply:
//Умножить
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 * fltArg2);
                     }
                    
break;
              case
eTokenDivide: //Разделить
                     {
                            double fltArg2 = Stack.back();
                            Stack.pop_back();
                            double fltArg1 = Stack.back();
                            Stack.pop_back();
                            Stack.push_back(fltArg1 / fltArg2);
                     }
                     break;
              case eTokenFunction:
//Функция
                     {
                            if (token.GetText() == "sin")
//Синус
                            {
                                   double fltArg = Stack.back();
                                   Stack.pop_back();
                                   Stack.push_back(sin(fltArg));
                            }
                            else if (token.GetText() == "cos") //Косинус
                            {
                                   double fltArg = Stack.back();
                                   Stack.pop_back();
                                   Stack.push_back(cos(fltArg));
                            }
                            else if (token.GetText() == "sqrt") //Корень квадратный
                            {
                                   double fltArg = Stack.back();
                                   Stack.pop_back();
                                   Stack.push_back(sqrt(fltArg));
                            }
                     }
                     break;

       }
}


А у нас требования к "идеальной программе". Как быть?


Далее...

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

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

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

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


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