Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.92/26: Рейтинг темы: голосов - 26, средняя оценка - 4.92
BigED
0 / 0 / 0
Регистрация: 14.12.2010
Сообщений: 26
1

Распознавание формулы со сложными математическими функциями в строке

14.12.2010, 13:28. Просмотров 4831. Ответов 9
Метки нет (Все метки)

Задание курсовика - распознать формулу функции введенную с клавиатуры и построить ее график (прикручу графику позже, сам код уже написан мной для лабы, да и мелочи буду вылизывать в конце), нашел превосходный способ распознавания, допилил и модифицировал его под себя, так что остался только один не решенный вопрос о том, как можно реализовать распознавание матем. функций, на подобии sin, cos, log и других, на мой взгляд основная сложность заключается в том что бы распознать то что находиться у этих функций в скобках, не представляю как это можно реализовать, да и к тому же надо будет учитывать одз, хотя возможно есть и другие подводные камни о которых я и не ведаю (пока), хотелось бы услышать практических советов или примерчика какого нибудь, заранее благодарю)
До этого начинал с работать с польской записью, но этот метод, в плане вычисления показался мне несколько проще - проще реализация вычисления "сложных" выражений содержащих в перемешку разные по приоритету операции.
Пишу на чистом Си, в BorlandC 3.1 Сам код, избавленный от моих попыток научить программу понимать мат. функции:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <math.h>
      #include <ctype.h>
      #include <conio.h>
       
      int next();
      void skip(int t);
      double expr();
      double numpar();
      double factor();
      double term();
      double x=5;
      int i=0; char s[50]; int Op; double tokval;
      int main()
      {
              clrscr();
              gets(s);
              //for(;x<10;x+=1)
              //{
                      next();
                      printf("\n%.9g\n", expr());
              //        i=0;
              //        Op=0;
              //        tokval=0;
              //}
              if(!getch()) getch();
              clrscr();
              return 0;
      }
      int next()
      {
      int c,count=0;
      char cbuf[50];
              for (;;)
              {
                      c=s[i++];
                      if(strchr("+-*/^()\n",c)!=NULL&&i!=1)
                         if(c=='*'&&s[i]=='*')
                              {
                                      i=i+1;
                                      return Op='^';
                              }
                         else
                             return Op=c;
                      if(c=='s'&&s[i]=='i'&&s[i+1]=='n')
                              {
                                      i=i+2;
                                      return Op='s';
                              }
                      if(isspace(c)) continue;
                      if(isdigit(c)||c=='.'||c=='x'||c=='-')
                      {
                             if(c=='x')
                              {
                                      tokval=x;
                                      return Op='n';
                              }
                              for(;((c>='0'&&c<='9')||c=='.'||c=='-');)
                              {
                                      cbuf[count++]=c;
                                      cbuf[count]='\0';
                                      c=s[i++];
                              }
                              i-=1;
                              tokval=atof(cbuf);
                              return Op='n';
                      }
                      printf("Bad character: %c\n",c);
                      if(!getch()) getch();
              }
      }
       
      void skip(int t)
      {
              if(Op!=t)
                       {
                              printf("You take a error, try agan");
                              if(!getch()) getch();
                              exit(1);
                       }
              next();
      }
       
      // numpar ::= number | '(' expr ')'
      double numpar()
      {
              if (Op=='n')
              {
                      double res=tokval;
                      skip('n');
                      return res;
              }
              skip('(');
              double res=expr();
              skip(')');
              return res;
      }
      // factor ::= numpar | numpar '^' factor
      double factor()
      {
              double res=numpar();
              if (Op=='^')
              {
                      skip('^');
                      res=pow(res,factor());
              }
              return res;
      }
      // term ::= factor | term '*' factor | term '/' factor
      double term()
      {
              double res=factor();
              for (;;)
              {
                      if (Op=='*')
                      {
                              skip('*');
                              res*=factor();
                      }
                    else
                    if (Op=='/')
                      {
                              skip('/');
                              res/=factor();
                      }
                    else
                    return res;
              }
      }
      // expr ::= term | expr '+' term | expr '-' term
      double expr()
      {
              double res=term();
              for (;;)
              {
                      if (Op=='+')
                      {
                              skip('+');
                              res+=term();
                      }
              else
              if (Op=='-')
                      {
                              skip('-');
                              res-=term();
                      }
              else
              return res;
              }
      }
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.12.2010, 13:28
Ответы с готовыми решениями:

Задача с математическими функциями
Условие задания: Составьте программу, которая подсчитывает и выводит значение...

Циклы со сложными математическими выражениям, как правильно записать?!
Привет всем гуру Матлаб! Если у Вас найдется свободная минутка :-Картинка 1 Не...

Генерация исключительных ситуаций математическими функциями
Здравствуйте! Должна ли возникать и как сделать генерацию исключительной...

Работа с математическими функциями sin и cos
Добрый день! Создаю приложение в windows forms, нужно взять cos и sin. Вроде...

Что импортировать, чтобы пользоваться математическими функциями?
Установил Microsoft Visual Studio Community 2015. VB не не понимает...

9
EVP
509 / 271 / 60
Регистрация: 14.12.2010
Сообщений: 547
14.12.2010, 22:05 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
char sid[50];
...
int next()
{
    int c,count=0;
    char cbuf[50];
    for (;;)
    {
        c=s[i++];
        if(strchr("+-*/^()\n",c)!=NULL&&i!=1)
            if(c=='*'&&s[i]=='*')
            {
                    i=i+1;
                    return Op='^';
            }
            else
                return Op=c;
        /*if(c=='s'&&s[i]=='i'&&s[i+1]=='n')
        {
            i=i+2;
            return Op='s';
        }// */
        if(isspace(c)) continue;
        if(isdigit(c)||c=='.'||c=='x'||c=='-')
        {
            if(c=='x')
            {
                tokval=x;
                return Op='n';
            }
            for(;((c>='0'&&c<='9')||c=='.'||c=='-');)
            {
                cbuf[count++]=c;
                cbuf[count]='\0';
                c=s[i++];
            }
            i-=1;
            tokval=atof(cbuf);
            return Op='n';
        }
    if(isalpha(c))
    {
        do
        {
            cbuf[count++]=c;
            cbuf[count]='\0';
            c=s[i++];
        }
        while(isalpha(c));
        strcpy(sid,cbuf);
        i--;
        return Op = 'a';//alpha function
    }
 
        printf("Bad character: %c\n",c);
        if(!getch()) getch();
    }
}
...
// numpar ::= number | '(' expr ')' | (sin||cos||log) '(' expr ')'
double numpar()
{
    if (Op=='n')
    {
        double res=tokval;
        skip('n');
        return res;
    }
    
    if ('a' == Op)
    {
        skip('a');
        
        skip('(');
        double res=expr();
        skip(')');
 
        if (0==strcmp(sid,"sin"))
            res = sin(res);
        else if (0==strcmp(sid,"cos"))
            res = cos(res);
        else if (0==strcmp(sid,"log"))
            res = log(res);
        else
        {
            printf("Unknown function: %s\n",sid);
            res = 0;
        }
 
        return res;
    }
 
    skip('(');
    double res=expr();
    skip(')');
    return res;
}
...
Ненадежно определяются числа, например:
1 + ( 2 - 1 ) * 3
даёт правильные 4.
А строка:
1+(2-1)*3
неправильные 7

Следует доработать разбор числа..
1
BigED
0 / 0 / 0
Регистрация: 14.12.2010
Сообщений: 26
14.12.2010, 23:00  [ТС] 3
спасибо огроменное, а то уже кучу вариаций перебрал, но так и не сделал рабочий вариант, который бы понимал формулу в функциях, максимум число
за ошибку отдельное спасибо, преподаватель бы заметил, он всегда все замечает) буду поправлять
как защищу выложу то что выйдет здесь, тема как я понял актуальная
0
silent_1991
Эксперт С++
5013 / 3073 / 271
Регистрация: 11.11.2009
Сообщений: 7,045
Завершенные тесты: 1
15.12.2010, 00:30 4
Вот, недавно писал распознаватель выражений любой сложности, понимает все стандартные функции библиотеки cmath, прикрутить другие проблем не составит. Правда получилось несколько громоздко:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <cmath>
#include <cstring>
 
double number(std::string &, unsigned &);
 
double identifier(std::string &, unsigned &);
 
double function(std::string &, std::string &, unsigned &);
 
double base(std::string &, unsigned &);
 
double expr(std::string &, unsigned &);
double term(std::string &, unsigned &);
double factor(std::string &, unsigned &);
 
double calculate(std::string &);
 
std::map< std::string, double > vars;
 
/*
 
<цифра> ::= '0' | ... | '9' |
<буква> ::= 'a' ... 'z' | 'A' ... 'Z' | '_'
 
<число> ::= <цифра> {<цифра>} [ '.' <цифра> {<цифра>} ]
 
<операция_+_-> ::= '+' | '-'
<операция_*_/> ::= '*' | '/'
<унарный_+_->  ::= '+' | '-'
 
<идентификатор> ::= <буква> { <буква> | <цифра> }
 
<переменная> ::= <идентификатор>
<функция>    ::= <идентификатор> '(' <выражение> ')'
 
<основание> ::= <переменная> | <функция> | <число> | ( '(' <выражение> ')' )
 
<выражение> ::= <слагаемое> [ <операция_+_-> <слагаемое>]
<слагаемое> ::= <множитель> [ <операция_*_/> <множитель>]
<множитель> ::= [ <унарный_+_-> ] <множитель> | <основание> [ '^' <множитель> ]
 
*/
 
int main()
{
    std::string str;
 
    setlocale(LC_ALL, "Rus");
 
    std::cout << "Введите выражение: ";
    std::cin >> str;
 
    std::cout << std::setprecision(12) << "Результат вычисления: " << calculate(str) << std::endl;
 
    std::cin.get();
    std::cin.get();
    return 0;
}
 
double number(std::string &str, unsigned &index)
{
    double result = 0.0;
    char digit;
    double k = 10.0;
 
    while (index < str.length())
    {
        digit = str[index++];
 
        if (digit >= '0' && digit <= '9')
            result = result * 10.0 + (digit - '0');
        else
        {
            --index;
            break;
        }
    }
 
    if (index < str.length())
        digit = str[index++];
 
    if (digit == '.')
    {
        while (index < str.length())
        {
            digit = str[index++];
 
            if (digit >= '0' && digit <= '9')
            {
                result += (digit - '0') / k;
                k *= 10.0;
            }
            else
            {
                --index;
                break;
            }
        }
    }
    else
        --index;
 
    return result;
}
 
double identifier(std::string &str, unsigned &index)
{
    std::string name = "";
    double result;
 
    while (index < str.length() &&
           ((str[index] >= 'a' && str[index] <= 'z') ||
            (str[index] >= 'A' && str[index] <= 'Z') ||
            (str[index] >= '0' && str[index] <= '9') ||
            (str[index] == '_')))
        name += str[index++];
 
    if (index < str.length() && str[index] == '(')
    {
        ++index;
        result = function(name, str, index);
 
        if (index >= str.length() || str[index] != ')')
        {
            std::cout << "Ожидается \")\" в позиции " << index + 2 << std::endl;
            exit(-1);
        }
 
        ++index;
    }
    else
    {
        double var;
 
        std::cout << "Введите значение переменной " << name << ": ";
        std::cin >> var;
 
        vars.insert(std::pair< const std::string, double > (name, var));
 
        result = vars[name];
    }
 
    return result;
}
 
double function(std::string &name, std::string &str, unsigned &index)
{
    double argument = expr(str, index);
 
    if (strcmp(name.c_str(), "acos") == 0)
        return acos(argument);
 
    if (strcmp(name.c_str(), "asin") == 0)
        return asin(argument);
 
    if (strcmp(name.c_str(), "atan") == 0)
        return atan(argument);
 
    if (strcmp(name.c_str(), "cos") == 0)
        return cos(argument);
 
    if (strcmp(name.c_str(), "cosh") == 0)
        return cosh(argument);
 
    if (strcmp(name.c_str(), "exp") == 0)
        return exp(argument);
 
    if (strcmp(name.c_str(), "log") == 0)
        return log(argument);
 
    if (strcmp(name.c_str(), "log10") == 0)
        return log10(argument);
 
    if (strcmp(name.c_str(), "sin") == 0)
        return sin(argument);
    
    if (strcmp(name.c_str(), "sinh") == 0)
        return sinh(argument);
 
    if (strcmp(name.c_str(), "sqrt") == 0)
        return sqrt(argument);
 
    if (strcmp(name.c_str(), "tan") == 0)
        return tan(argument);
 
    if (strcmp(name.c_str(), "tanh") == 0)
        return tanh(argument);
 
    std::cout << "Неизвестная функция" << std::endl;
    exit(-1);
}
 
double base(std::string &str, unsigned &index)
{
    double result;
 
    if (index >= str.length())
    {
        std::cout << "Неожиданный конец строки" << std::endl;
        exit(-1);
    }
 
    if (str[index] == '(')
    {
        ++index;
        result = expr(str, index);
 
        if (index >= str.length() || str[index] != ')')
        {
            std::cout << "Ожидается \")\" в позиции " << index + 2 << std::endl;
            exit(-1);
        }
 
        ++index;
    }
    else
    {
        if (str[index] >= '0' && str[index] <= '9')
            result = number(str, index);
        else
        {
            if ((str[index] >= 'A' && str[index] <= 'Z') ||
                (str[index] >= 'a' && str[index] <= 'z') ||
                (str[index] == '_'))
                result = identifier(str, index);
            else
            {
                std::cout << "Некорректный символ в позиции " << index + 1 << std::endl;
                exit(-1);
            }
        }
    }
 
    return result;
}
 
double expr(std::string &str, unsigned &index)
{
    double result;
    char operation;
 
    result = term(str, index);
 
    while (index < str.length() && 
           (str[index] == '+' || str[index] == '-'))
    {
        operation = str[index];
        ++index;
 
        switch (operation)
        {
        case '+':
            result += term(str, index);
            break;
        case '-':
            result -= term(str, index);
            break;
        }
    }
 
    return result;
}
 
double term(std::string &str, unsigned &index)
{
    double result;
    char operation;
    double div;
 
    result = factor(str, index);
 
    while (index < str.length() && 
           (str[index] == '*' || str[index] == '/'))
    {
        operation = str[index];
        ++index;
 
        switch (operation)
        {
        case '*':
            result *= factor(str, index);
            break;
        case '/':
            div = factor(str, index);
 
            if (div == 0.0)
            {
                std::cout << "Деление на нуль!" << std::endl;
                exit(-1);
            }
 
            result /= div;
            break;
        }
    }
 
    return result;
}
 
double factor(std::string &str, unsigned &index)
{
    double result;
 
    if (index >= str.length())
    {
        std::cout << "Неожиданный конец строки" << std::endl;
        exit(-1);
    }
 
    switch (str[index])
    {
    case '+':
        ++index;
        result = factor(str, index);
        break;
    case '-':
        ++index;
        result = -factor(str, index);
        break;
    default:
        result = base(str, index);
 
        if (index <= str.length() - 1 && str[index] == '^')
        {
            ++index;
            result = pow(result, factor(str, index));
        }
    }
 
    return result;
}
 
double calculate(std::string &str)
{
    unsigned index = 0;
    double result = expr(str, index);
 
    if (index < str.length() - 1)
    {
        std::cout << "Некорректный символ в позиции " << index + 1<< std::endl;
        exit(-1);
    }
 
    return result;
}
5
BigED
0 / 0 / 0
Регистрация: 14.12.2010
Сообщений: 26
27.12.2010, 21:40  [ТС] 5
Спасибо всем за помощь, защитился на отлично
Как и обещал:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <conio.h>
#include <alloc.h>
#include <graphics.h>
#include <DOS.h>
#define pi 3.14159265
int next(char *s,char *sid);
int skip(int t, char *s,char *sid);
double expr(char *s,char *sid);
double numpar(char *s,char *sid);
double factor(char *s,char *sid);
double term(char *s,char *sid);
void test();
int mod(char *s);
int graph(char *s,char *sid);
 
struct Operation
{
       char* sid[7];
       int Op;
       double tokval;
       double x;
}Oper={"sin","cos","tg","ctg","sqrt","log","exp"};
 
int main()
{
char c;
int i=0;
char *s,sid[6];
int blocknum=0;
int gd=DETECT,gm,err;
    heapinfo hi;
    hi.ptr=NULL;
    clrscr();
    printf("\nEnter the formula\n");
    fflush(stdin);
    s=(char*)realloc(s,++i*sizeof(char));
    s[i-1]='(';
    while((c=getch())!=13)
    {
        if(c==8) continue;
        fflush(stdin);
        putch(c);
        s=(char*)realloc(s,++i*sizeof(char));
        if(s==NULL)
        {
                printf("\n memory error");
                if(!getch()) getch();
                return -1;
        }
        s[i-1]=c;
    }
    s=(char*)realloc(s,++i*sizeof(char));
    s[i-1]=')';
    s[i]='\0';
    mod(s);
    while(heapwalk(&hi)==_HEAPOK)
    if(hi.in_use) ++blocknum;
    test();
    clrscr();
    detectgraph(&gd,&gm);
    err=graphresult();
    if(err)
    {
        printf("\n%s",grapherrormsg(err));
        return 1;
    }
    registerbgidriver(EGAVGA_driver);
    initgraph(&gd,&gm,"");
    err=graphresult();
    if(err)
    {
        printf("n%s",grapherrormsg(err));
        return 2;
    }
    cleardevice();
    clrscr();
    graph(s,sid);
    if(!getch()) getch();
    free(s);
    hi.ptr=NULL;
    while (heapwalk(&hi)==_HEAPOK)
          if(hi.in_use)
             --blocknum;
          if(blocknum)
            printf("\n Error: Useing block in heap \n");
    clrscr();
    closegraph();
    return 0;
}
int mod(char *s)
{
int a,j,n=0,i=0;
    a=strlen(s);
    for(i=0;s[i]!='\0';i++)
    {
        if(s[i]=='-')
        {
                if(s[i-1]=='(')
                {
                        for (j=0;j!=a+1-i;j++) s[(a+1)-j]=s[a-j];
                        s[i]='0';
                }
        }
    }
    a=strlen(s);
    for(i=0;i<a;i++)
    {
        if(s[i]=='(') n=n+1;
        if(s[i]==')') n=n-1;
    }
    if(n!=0)
    {
        closegraph();
        printf("\nYou take a error, try agan");
        if(!getch()) getch();
        exit(1);
    }
    return 0;
}
 
int next(char *s,char *sid)
{
int c,count=0;
static int i=0;
char cbuf[50];
    if(Oper.Op=='Ж') i=0;
    for (;;)
    {
        c=s[i++];
        if(strchr("+-*/^()\n",c)!=NULL&&i!=1)
        {
            if(c=='*'&&s[i]=='*')
            {
                    i=i+1;
                    return Oper.Op='^';
            }
            return Oper.Op=c;
        }
        if(isspace(c)) continue;
        if(isdigit(c)||c=='.'||c=='x')
        {
 
                        for(;(c=='x'||(c>='0'&&c<='9')||c=='.');)
                        {
                                if(c=='x')
                                     {
                                        if(s[i-i]=='-') Oper.tokval=-1*Oper.x;
                                        else
                                        Oper.tokval=Oper.x;
                                        return Oper.Op='n';
                                     }
                                cbuf[count++]=c;
                                cbuf[count]='\0';
                                c=s[i++];
                        }
                        i-=1;
                        Oper.tokval=atof(cbuf);
                        return Oper.Op='n';
        }
        if(isalpha(c))
        {
                if(c=='p'&&s[i++]=='i')
                {
                        Oper.tokval=pi;
                        return Oper.Op='n';
 
                }
                do
                {
                        cbuf[count++]=c;
                        cbuf[count]='\0';
                        c=s[i++];
                }
                while(isalpha(c));
                strcpy(sid,cbuf);
                i--;
                return Oper.Op='a';//alpha function
        }
    }
}
int skip(int t,char *s,char *sid)
{
    if(Oper.Op!=t)
    {
        closegraph();
        printf("\nYou take a error, try agan");
        if(!getch()) getch();
        exit(1);
    }
    next(s,sid);
    return 0;
}
 
// numpar ::= number | '(' expr ')' | (func1||...||func2) '(' expr ')'
double numpar(char *s,char *sid)
{
int i=0,j=0;
    if (Oper.Op=='n')
    {
        double res=Oper.tokval;
        skip('n',s,sid);
        return res;
    }
    if (Oper.Op=='a')
    {
        skip('a',s,sid);
        skip('(',s,sid);
        double res=expr(s,sid);
        skip(')',s,sid);
        for(i=0;(strcmp(sid,Oper.sid[i])!=0);i++);
        switch(i)
        {
                case 0: res=sin(res); break;
                case 1: res=cos(res); break;
                case 2: res=sin(res)/cos(res); break;
                case 3: res=cos(res)/sin(res); break;
                case 4: if(res>=0) res=sqrt(res);
                        else
                        {
                                res=res+getmaxx()/2;
                                res=sqrt(res);
                        }
                        break;
                case 5: if(res>=0) res=log(res);
                        else
                        {
                                res=res+getmaxx()/2;
                                res=log(res);
 
                        }
                break;
                case 6: res=exp(res); break;
                default: closegraph(); printf("\nBad function: %s\n",sid);res=0;
        }
        return res;
    }
    skip('(',s,sid);
    double res=expr(s,sid);
    skip(')',s,sid);
    return res;
}
// factor ::= numpar | numpar '^' factor
double factor(char *s,char *sid)
{
    double res=numpar(s,sid);
    if (Oper.Op=='^')
 
    {
        skip('^',s,sid);
        res=pow(res,factor(s,sid));
    }
    return res;
}
// term ::= factor | term '*' factor | term '/' factor
double term(char *s,char *sid)
{
double temp;
    double res=factor(s,sid);
    for (;;)
    {
        if (Oper.Op=='*')
        {
                skip('*',s,sid);
                res*=factor(s,sid);
        }
        else
        if (Oper.Op=='/')
        {
                skip('/',s,sid);
                temp=factor(s,sid);
                if(temp!=0) res/=temp;
                else
                {
                     temp=temp+0.001;
                     res/=temp;
                }
        }
        else
        return res;
    }
}
// expr ::= term | expr '+' term | expr '-' term
double expr(char *s,char *sid)
{
    double res=term(s,sid);
    for (;;)
        {
                if (Oper.Op=='+')
                {
                        skip('+',s,sid);
                        res+=term(s,sid);
                }
                else
                if (Oper.Op=='-')
                {
                        skip('-',s,sid);
                        res-=term(s,sid);
                }
                else
                return res;
 
 
        }
}
 
void test()
{
char s[]="(sin(pi)^2+cos(pi)^2)";
char sid[6];
     next(s,sid);
     if(sin(pi)*sin(pi)+cos(pi)*cos(pi)!=expr(s,sid))
     {
        clrscr();
        printf("\nTest failed");
        if(!getch()) getch();
        exit(1);
     }
     Oper.Op='Ж';
     Oper.tokval=0;
}
int graph(char *s,char *sid)
{
float a,b,i;
int xmax,ymax,px,py,x0,y0;
        a=-4;
        b=4;
        xmax=getmaxx()+1;
        ymax=getmaxy()+1;
        px=100;
        py=100;
        x0=xmax/2;
        y0=ymax/2;
 
        for(;;)
        {
                if(((xmax/2+b*px)>xmax)||((xmax/2+a*px)<0))
                {
                        next(s,sid);
                        putpixel(xmax/2+Oper.x*px,ymax/2-expr(s,sid)*py,WHITE);
                        px=px-1;
                        py=py-1;
                        Oper.Op='Ж';
                        Oper.tokval=0;
                        continue;
                }
                bar(0,0,xmax,ymax);
                setfillstyle(SOLID_FILL,WHITE);
                setcolor(GREEN);
                setlinestyle(SOLID_LINE,0,3);
                line(0,y0,xmax,y0);
                line(x0,0,x0,ymax);
                line(xmax,y0,xmax-20,y0+10);
                line(xmax,y0,xmax-20,y0-10);
                line(x0,0,x0-10,0+20);
                line(x0,0,x0+10,0+20);
                setlinestyle(DASHED_LINE,0,2);
                for(i=x0;i<xmax;i+=px) line(i,0,i,ymax);
                for(i=x0;i>0;i-=px) line(i,0,i,ymax);
                for(i=y0;i>0;i-=py) line(0,i,xmax,i);
                for(i=y0;i<ymax;i+=py) line(0,i,xmax,i);
                setlinestyle(DOTTED_LINE,0,2);
                for(i=x0;i<xmax;i+=(px/10)) line(i,0,i,ymax);
                for(i=x0;i>0;i-=(px/10)) line(i,0,i,ymax);
                for(i=y0;i>0;i-=(py/10)) line(0,i,xmax,i);
                for(i=y0;i<ymax;i+=(py/10)) line(0,i,xmax,i);
                setcolor(BROWN);
                setlinestyle(SOLID_LINE,0,3);
                circle(x0,y0,2);
                circle(x0+px,y0,2);
                circle(x0,y0-py,2);
                settextstyle(0,0,2);
                outtextxy(x0-18,y0+7,"0");
                outtextxy(x0+px,y0+14,"1");
                outtextxy(x0-14,y0-py,"1");
                outtextxy(xmax-25,y0+14,"X");
                outtextxy(x0-18,0+25,"Y");
                for(Oper.x=a;Oper.x<b;Oper.x+=(b-a)/xmax)
                   {
                        next(s,sid);
                        putpixel(xmax/2+Oper.x*px,ymax/2-expr(s,sid)*py,BLUE);
                        delay(5);
                        Oper.Op='Ж';
                        Oper.tokval=0;
                   }
                break;
        }
        return 0;
}
0
ForEveR
В астрале
Эксперт С++
8002 / 4760 / 653
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
28.12.2010, 11:44 6
silent_1991, Красиво. Будет время - попробую тоже написать
0
silent_1991
Эксперт С++
5013 / 3073 / 271
Регистрация: 11.11.2009
Сообщений: 7,045
Завершенные тесты: 1
28.12.2010, 13:45 7
ForEveR, да там главное грамматику составить - а дальше всё по ней прогается. Чем мне этот способ и нравится (я вроде уже в подобной теме это говорил) - несколько строк грамматики - подробный план для будущей программы. Можно даже не понимать (это, конечно, плохо, но как вариант), как всё это в программе происходит, и всё равно правильно её написать, и всё, опять же, благодаря грамматике.
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,763
08.05.2016, 15:49 8
у меня ошибки выдает при компиляции на ваш код(27.12.2010, 22:40 [ТС] Распознавание формулы со сложными математическими функциями в строке).
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,763
08.05.2016, 15:51 9
Распознавание формулы со сложными математическими функциями в строке
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,763
08.05.2016, 16:06 10
silent_1991,хороший рабочий код.
Как сделать его что бы он понимал например 1/х вводим с клавиатуры или с файла строка,а сам х в цикле от -10 до 10 с шагом 0.1,то есть 200 значений получаем у.
Ведь по 200 значениям график построим.А вот с одним никак 1/(-10)
0
08.05.2016, 16:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.05.2016, 16:06

Распознавание типа данных в строке
Здравствуйте! Каким образом я могу получать признак неуспешной операции...

Распознавание в строке только чисел(игнор символов)
дана программа вычисления функции от одного значения до другого с шагом. Var...

Распознавание комментария по его расположению после заданной позиции в строке
Здравствуйте. Моя программа разбирает исходные строки ассемблерной программы на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru