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

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

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

       }
}


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


Далее...



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