v 0. Pasted by slipstak2 as cpp at 2011-01-22 14:15:11 MSK and set expiration to never.

Paste will expire never.

  1. #include <iostream>
  2. #include <cmath>
  3. #include <string.h>
  4.  
  5. using namespace std;
  6. const int MAX_SIZE = 200+10;
  7. const int MAX_FUNC_NAME = 3;
  8. char* funcName[] = {"sin","cos",0};
  9. double (*pfuncs[])(double) = {sin,cos};
  10.  
  11. bool ReadExp(char* &pos, double &res);
  12.  
  13. inline void SkipSpaces(char* &pos) {
  14.     while (*pos == ' ')
  15.         pos++;
  16. }
  17. inline bool isPlusOrMinus(char* &pos) {
  18.     //1. Пробелы могут быть: перед +,-
  19.     SkipSpaces(pos);
  20.     return '+' == *pos || '-' == *pos;
  21. }
  22. inline bool isMulOrDiv(char* &pos) {
  23.     // 2. Пробелы могут быть: перед *,/
  24.     SkipSpaces(pos);
  25.     return '*' == *pos || '/' == *pos;
  26. }
  27. inline bool isLetter(char* &pos) {
  28.     return
  29.         ('A' <= *pos && *pos <='Z') ||
  30.         ('a' <= *pos && *pos <='z');
  31. }
  32. inline bool isDigit(char* &pos) {
  33.     // <Цифра> = 0|1|2|3|4|5|6|7|8|9|
  34.     return '0' <= *pos && *pos <= '9';
  35. }
  36. inline bool isOpenBracket(char* &pos) {
  37.     // 3. Пробелы могут быть: перед (
  38.     SkipSpaces(pos);
  39.     return '(' == *pos;
  40. }
  41. inline bool isCloseBracket(char* &pos) {
  42.     // 4. Пробелы могут быть: перед )
  43.     SkipSpaces(pos);
  44.     return ')' == *pos;
  45. }
  46. bool isFuncBegin(char* &pos) {
  47.     // 6. Пробелы могут быть: перед именем функции
  48.     SkipSpaces(pos);
  49.     return isLetter(pos);
  50. }
  51. int FuncPos(char* fName) {
  52.     int pos = -1;
  53.     for (int i=0; funcName[i]!=0; i++) {
  54.         if (!strcmp(funcName[i],fName))
  55.             return i;
  56.     }
  57.     return pos;
  58. }
  59. bool isFracNumBegin(char* &pos) {
  60.     // 5. Пробелы могут быть: перед числом
  61.     SkipSpaces(pos);
  62.     return isDigit(pos);
  63. }
  64. bool ReadFuncName(char* &pos, int &funcPos) {
  65.     // <ИмяФункции> = "sin"|"cos"
  66.     char* fName = new char[MAX_FUNC_NAME+1];
  67.     int fNameLen = 0;
  68.     while (isLetter(pos)) {
  69.         fNameLen++;
  70.         pos++;
  71.     }
  72.     if (fNameLen>MAX_FUNC_NAME)
  73.         return false;
  74.  
  75.     // копирование происходит с учетом регистра
  76.     strncpy(fName,pos-fNameLen,fNameLen);
  77.     fName[fNameLen] = 0;
  78.  
  79.     funcPos = FuncPos(fName);
  80.     return funcPos != -1;
  81. }
  82. bool ReadFunc(char* &pos, double &res) {
  83.     // <Функция> = <ИмяФункции>(<Выражение>)
  84.     int funcPos = 0;
  85.     if (!ReadFuncName(pos, funcPos))
  86.         return false;
  87.  
  88.     if (isOpenBracket(pos)) {
  89.         pos++;
  90.         double arg = 0;
  91.         if (!ReadExp(pos,arg))
  92.             return false;
  93.         if (!isCloseBracket(pos))
  94.             return false;
  95.         pos++;
  96.  
  97.         res = pfuncs[funcPos](arg);         
  98.         return true;
  99.     }
  100.     else
  101.         return false;
  102. }
  103.  
  104. bool ReadFracNum(char* &pos, double &res) {
  105.     // <ДробноеЧисло> = <ЦелаяЧасть>|<ЦелаяЧасть>.<ДробнаяЧасть>
  106.     // <ЦелаяЧасть> = <Цифра>|<Цифра><Цифра>
  107.     double intPart = 0;
  108.     do
  109.     {
  110.         if (!isDigit(pos))
  111.             return false;
  112.         intPart = intPart*10 + *pos - '0';
  113.         pos++;
  114.     }
  115.     while (isDigit(pos));
  116.  
  117.     // <ДробнаяЧасть> = <Цифра>|<Цифра><Цифра>
  118.     double dblPart = 0;
  119.     if (*pos == '.') {
  120.         pos++;
  121.         double pow = 10;
  122.         do
  123.         {
  124.             if (!isDigit(pos))
  125.                 return false;
  126.             dblPart += (*pos - '0') / pow;
  127.             pow *=10;
  128.             pos++;
  129.  
  130.         } while (isDigit(pos));
  131.     }
  132.     res = intPart + dblPart;
  133.     return true;
  134. }
  135. bool ReadMul(char* &pos, double &res) {
  136.     // <Множитель> = +|- <ДробноеЧисло>|<Функция>|(<Выражение>)
  137.     bool isNeg = false;
  138.     if (isPlusOrMinus(pos)) {
  139.         isNeg = *pos == '-';
  140.         pos++;
  141.     }
  142.     if (isFracNumBegin(pos)) {
  143.         if (!ReadFracNum(pos,res))
  144.             return false;
  145.     }
  146.     else if (isFuncBegin(pos)) {
  147.         if (!ReadFunc(pos,res))
  148.             return false;
  149.     }
  150.     else if (isOpenBracket(pos)) {
  151.         pos++;
  152.         if (!ReadExp(pos,res))
  153.             return false;
  154.         if (!isCloseBracket(pos))
  155.             return false;
  156.         pos++;
  157.     }
  158.     else
  159.         return false;
  160.     res *= isNeg ? -1 : 1;
  161.     return true;
  162. }
  163. bool ReadOper(char* &pos, char &oper) {
  164.     oper = *pos++;
  165.     return true;
  166. }
  167. bool ReadTerm(char* &pos, double &res) {
  168.     // <Слагаемое> = <Множитель>{*|/<Множитель>}
  169.     if (!ReadMul(pos, res))
  170.         return false;
  171.     while (isMulOrDiv(pos)) {
  172.         char oper = 0;
  173.         if (!ReadOper(pos,oper))
  174.             return false;
  175.         double cur = 0;
  176.         if(!ReadMul(pos,cur))
  177.             return false;
  178.  
  179.         switch(oper) {
  180.             case '*': res *= cur; break;
  181.             case '/': res /= cur; break; // деление на ноль не будет по условию
  182.         }
  183.     }
  184.     return true;
  185. }
  186. bool ReadExp(char* &pos, double &res) {
  187.     // <Выражение> = <Слагаемое>{+|-<Слагаемое>}
  188.     do
  189.     {
  190.         double cur = 0;
  191.         if (!ReadTerm(pos,cur))
  192.             return false;
  193.         else
  194.             res += cur;
  195.     }
  196.     while (isPlusOrMinus(pos));
  197.    
  198.     // 7. Пробелы могут быть: в конце выражения
  199.     SkipSpaces(pos);
  200.  
  201.     return 0 == *pos || isCloseBracket(pos);
  202. }
  203. void input() {
  204.     char* buf = new char[MAX_SIZE];
  205.     memset(buf,0,sizeof(buf));
  206.     gets(buf);
  207.  
  208.     int initAddress = (int)buf;
  209.  
  210.     double res = 0.0;
  211.     if (ReadExp(buf,res))
  212.         printf("%0.3f",res);
  213.     else
  214.         printf("Error");
  215.  
  216.     buf = (char*) initAddress;
  217.     delete [] buf;
  218. }
  219. int main() {
  220.  
  221.     freopen("input.txt","r",stdin);
  222.     freopen("output.txt","w",stdout);
  223.     input();
  224.  
  225.     return 0;
  226. }


Editing is locked.