Форум программистов, компьютерный форум, киберфорум
Pascal (Паскаль)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Форумчанин Паскаля
 Аватар для code-n'-help
77 / 90 / 55
Регистрация: 08.11.2013
Сообщений: 399
Записей в блоге: 2

Идея калькулятора, подститывающего выражения

10.03.2014, 17:50. Показов 991. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ограмная просьба подкиньте идею как можно сделать свой калькулятор который бы считал выражения примера 2+2*2 или 567-564*3/567f yt ghjcnj 2+2 bkb 456-65. Подскажите как лутше!!! Можно ли это качественно сделать строками??? Нужна только идея хотя бы!

Добавлено через 23 часа 58 минут
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.03.2014, 17:50
Ответы с готовыми решениями:

Парсер математического выражения для калькулятора
Здравствуйте! Пишу курсач по про, нужен калькулятор в одну строку. Нашел готовый парсер в консоле, как мне сделать что бы это было в...

Как найти значение выражения без калькулятора.
как найти значение выражения 8¹⁶/16¹² без калькулятора

Идея
Предлагаю прятать в контенте страницы маленькое изображение размером 1х1px, которое будет играть роль ссылки на морду. Это изображение...

13
3030 / 1916 / 1649
Регистрация: 30.04.2011
Сообщений: 3,060
10.03.2014, 20:24
Цитата Сообщение от code-n'-help Посмотреть сообщение
Нужна только идея хотя бы!
Обратная польская запись
Там же и алгоритм
1
Форумчанин Паскаля
 Аватар для code-n'-help
77 / 90 / 55
Регистрация: 08.11.2013
Сообщений: 399
Записей в блоге: 2
10.03.2014, 22:58  [ТС]
Огромное спасибо за идею но дело в том что меня смущает то что в ОПЗ числа читаються через пробелы а в калькуляторах я не видел пробелов (
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
10.03.2014, 23:15
Цитата Сообщение от code-n'-help Посмотреть сообщение
Огромное спасибо за идею но дело в том что меня смущает то что в ОПЗ числа читаються через пробелы а в калькуляторах я не видел пробелов
А ты видел калькуляторы, у которых выражение вводится в ОПЗ? (Они есть, если что...)

Добавлено через 1 минуту
(Если я правильно понял, вопрос был про наличие операции занесения числа в стек.)
1
Форумчанин Паскаля
 Аватар для code-n'-help
77 / 90 / 55
Регистрация: 08.11.2013
Сообщений: 399
Записей в блоге: 2
11.03.2014, 22:26  [ТС]
Нет дело в том что в этой статье написано что все числа заносятся в стек и они отделены пробелами (((. Или я не правильно понял?
0
 Аватар для golandy
73 / 73 / 20
Регистрация: 11.01.2014
Сообщений: 252
Записей в блоге: 2
11.03.2014, 23:39
так а что мешает из строки удалить пробелы и работать с ней
а польская запись самое то, сам раньше писал
0
Модератор
10445 / 5737 / 3406
Регистрация: 17.08.2012
Сообщений: 17,451
12.03.2014, 01:43
golandy, числа сольются.
0
 Аватар для golandy
73 / 73 / 20
Регистрация: 11.01.2014
Сообщений: 252
Записей в блоге: 2
12.03.2014, 12:51
так а строку можно выводить ту что и ввели, а для работы внутри проги сделать временную с которой и работать
0
Модератор
10445 / 5737 / 3406
Регистрация: 17.08.2012
Сообщений: 17,451
12.03.2014, 13:03
golandy, нет, надо просто строку отпарсить и разобрать по косточкам, и все дела. И работать не со строкой, а с массивом/массивами из операндов и операций.
0
 Аватар для golandy
73 / 73 / 20
Регистрация: 11.01.2014
Сообщений: 252
Записей в блоге: 2
12.03.2014, 13:10
Cyborg Drone, спорить не буду т.к. сколько людей столько и решений. Я просто предложил вариант если нужно вводить строку с пробелами. Можно и ее просто попарсить. А по этой теме много примеров в сети. Только определиться с методом польской записи (постфиксная, префиксная).
0
Модератор
10445 / 5737 / 3406
Регистрация: 17.08.2012
Сообщений: 17,451
12.03.2014, 13:28
На месте ТС я бы слизал интерфейс с калькуляторов Электроника МК-54" или Электроника МК-61", в них используется ОПЗ. Только стек бы сделал побольше, и индицировал бы все элементы стека, операций поменьше и никакой записи программ, последние два пункта для простоты. Однако, на чистом паскале такое сделать тяжело. code-n'-help, в сети можно найти эмуляторы вышеназванных калькуляторов. И вообще, так как ОПЗ, кнопки [=] в таком калькуляторе нет по определению.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
12.03.2014, 14:43
Лучший ответ Сообщение было отмечено Kodzaev как решение

Решение

Если интересно, есть один такой калькулятор. Вроде работает, хотя, возможно, ошибки есть. Только код страшненький - это я давно писал, когда классе в 10-м учился.
Pascal
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
{$A+,B-,D+,E-,F-,G+,I+,L+,N+,O-,P-,Q+,R+,S+,T-,V+,X+}
{$M 16384,0,655360}
uses crt;
const specstr: string= 'sin#####cos#####ln######exp#####sqr#####'+
                       'sqrt####pi######log#####';
      specl: array[1..8] of word=(3,3,2,3,3,4,2,3);
      max=60;
type func=(none,sin0,cos0,ln0,exp0,sqr0,sqrt0,pi0,log0);
     funcpar= record
              f:func; par:word;
              end;
const parcount: array [func] of word=
                ($FFFF,1,1,1,1,1,1,0,2);
type stelem= record
             case t:(num,act) of
                  num: (n:double);
                  act: (a:char; fn:func);
             end;
 
var s:string;
    i,k,poss:word;
    res:double;
 
function prior(op:char):word;
begin
case op of
     '^': prior:=4;
     '*','/': prior:=3;
     '+','-': prior:=2;
     ';': prior:=1;
     '(': prior:=0;
     end;
end;
 
function calc(const s:string; var res:double; var poss:word):word;
var st,st1,st2:array [0..max] of stelem;
    br:array [0..max] of funcpar;
    lst:(oper,number,fname);
    lstfnc:func;
    n,ns,n1,n2,t,nb:word;
    n_:word absolute n;
    ts:string;
    lt:byte absolute ts;
    l:byte absolute s;
    c:char;
    e:integer;
    dd:double;
 
function processnum:boolean;
begin
while s[ns+1] in ['0'..'9'] do begin
      if lt=255 then begin processnum:=false; exit; end;
      inc(ns); inc(lt); ts[lt]:=s[ns];
      end;
processnum:=true;
end;
 
label 0;
begin
n1:=0; n2:=0; n:=0; ns:=0; nb:=0; lst:=oper;
repeat
inc(ns); lt:=1; ts[1]:=s[ns]; c:=s[ns];
if (lst=oper) and (c in ['+','-']) then begin
   if c='-' then begin
      inc(n,2);
      if n>=max then begin calc:=1; poss:=ns; exit; end;
      with st[n-1] do begin t:=num; n:=0; end;
      with st[n] do begin t:=act; a:='-'; end;
      end;
   continue;
   end else
if c=#32 then continue else
if c in ['*','+','-','/','^',';'] then
   begin
   if lst<>number then begin calc:=14; poss:=ns; exit; end; lst:=oper;
   if c=';' then if nb=0 then begin calc:=13; poss:=ns; exit; end
                         else with br[nb] do begin
                              inc(par);
                              if par>parcount[f] then begin
                                 calc:=5; poss:=ns; exit;
                                 end;
                              end;
   inc(n); if n>max then begin calc:=1; poss:=ns; exit; end;
   with st[n] do begin t:=act; a:=ts[lt]; end;
   end else
if c='(' then begin
   if lst=number then begin calc:=14; poss:=ns; exit; end; {lst:=oper below}
   if nb=max then begin calc:=2; poss:=ns; exit; end;
   inc(nb);
   with br[nb] do begin
        if lst=fname then f:=lstfnc else f:=none;
        par:=0;
        end;
   lst:=oper;
   if n>max then begin calc:=1; poss:=ns; exit; end;
   inc(n); with st[n] do begin t:=act; a:=c; end;
   end else
if c=')' then begin
   if (lst<>number) and (parcount[lstfnc]<>0) then begin
      calc:=14; poss:=ns; exit;
      end;
   lst:=number;
   if nb=0 then begin calc:=3; poss:=ns; exit; end;
   if n>max then begin calc:=1; poss:=ns; exit; end;
   inc(n); with st[n] do begin t:=act; a:=c; fn:=br[nb].f; end;
   dec(nb);
   end else
if c in ['a'..'z'] then
   begin
   if lst<>oper then begin calc:=14; poss:=ns; exit; end; lst:=fname;
   while s[ns+1] in ['a'..'z'] do begin
         inc(ns); inc(lt); ts[lt]:=s[ns];
         end;
   t:=pos(ts,specstr);
   if (t and 7<>1) or (specl[t shr 3+1]<>lt) then begin calc:=4; exit; end;
   lstfnc:=func(t shr 3+1);
   end else
if c=#0 then break else
if c in ['0'..'9'] then begin 0:
   if lst<>oper then begin calc:=14; poss:=ns; exit; end; lst:=number;
   if not processnum then begin calc:=6; poss:=ns; exit; end;
   if s[ns+1]='.' then begin
      inc(ns); inc(lt); ts[lt]:='.';
      if not processnum then begin calc:=6; poss:=ns; exit; end;
      end;
   if s[ns+1]='e' then begin
      inc(ns); inc(lt); ts[lt]:='e';
      if s[ns+1] in ['+','-'] then begin
         inc(ns); inc(lt); ts[lt]:=s[ns];
         end;
      if not processnum then begin calc:=6; poss:=ns; exit; end;
      end;
   if n=max then begin calc:=1; poss:=ns; exit; end;
   inc(n);
   with st[n] do begin t:=num; val(ts,n,e); end;
   if e<>0 then begin calc:=7; poss:=ns; exit; end;
   end else
{*}begin calc:=9; poss:=ns; exit; end;
until false;
if nb<>0 then begin calc:=8; poss:=ns; exit; end;
(**************************************************)
fillchar(st2,sizeof(st1)*2,0);
for n:=1 to n do
    with st[n] do begin
         if t=num then begin
            if n1=max then begin calc:=10; poss:=ns; exit; end;
            inc(n1); st1[n1]:=st[n_];
            end else
         if a='(' then begin
            if n2=max then begin calc:=10; poss:=ns; exit; end;
            inc(n2); st2[n2]:=st[n_];
            end else
         if a=')' then begin
            while (st2[n2].t<>act) or (st2[n2].a<>'(') do begin
                  if n1=max then begin calc:=10; poss:=ns; exit; end;
                  inc(n1); st1[n1]:=st2[n2]; dec(n2);
                  end;
            dec(n2); inc(n1);
            if n1=max then begin calc:=10; poss:=ns; exit; end;
            st1[n1]:=st[n_];
            end else
         {*}begin
            while (n2>0) and (prior(a)<=prior(st2[n2].a)) do begin
                  if n1=max then begin calc:=10; poss:=ns; exit; end;
                  inc(n1); st1[n1]:=st2[n2]; dec(n2);
                  end;
            if n2=max then begin calc:=10; poss:=ns; exit; end;
            inc(n2); st2[n2]:=st[n_];
            end;
         end;
while n2>0 do begin
      if n1=max then begin calc:=10; poss:=ns; exit; end;
      inc(n1); st1[n1]:=st2[n2]; dec(n2);
      end;
(************************************************************)
n:=0;
for n1:=1 to n1 do begin
    if st1[n1].t=num then begin
       inc(n); st[n]:=st1[n1];
       end else
    {*}if st1[n1].a in ['*','+','-','/','^',';'] then begin
          if n and $FFFE=0 then
             begin calc:=11; poss:=ns; exit; end;
          dec(n);
          with st[n] do
               case st1[n1].a of
                    '+': n:=n+st[n_+1].n;
                    '-': n:=n-st[n_+1].n;
                    '*': n:=n*st[n_+1].n;
                    '/': n:=n/st[n_+1].n;
                    '^': n:=exp(ln(n)*st[n_+1].n);
                    ';': inc(n_);
                    end;
          end
       else if st1[n1].fn=none then continue
       else begin
            if n<parcount[st1[n1].fn] then
               begin calc:=11; poss:=ns; exit; end;
            with st[n] do
                 case st1[n1].fn of
                      sin0: n:=sin(n);
                      cos0: n:=cos(n);
                      ln0:  n:=ln(n);
                      exp0: n:=exp(n);
                      sqr0: n:=sqr(n);
                      sqrt0:n:=sqrt(n);
                      pi0:  begin inc(n_); st[n_].n:=pi; end;
                      log0: begin
                            dec(n_);
                            st[n_].n:=ln(n)/ln(st[n_].n);
                            end;
                      end;
            end;
    end;
if n<>1 then begin calc:=12; poss:=ns; exit; end;
res:=st[1].n;
calc:=0;
end;
 
begin
textattr:=7; clrscr;
write('Введите выражение: ');
readln(s);
s[length(s)+1]:=#0;
for i:=0 to $FFFF do
    if (s[i]>'A') and (s[i]<'Z') then s[i]:=char(byte(s[i]) or $20)
    else if s[i]=#0 then break;
k:=calc(s,res,poss);
if k<>0 then begin
   write('>>>Ошибка ',k,'<<<'); readln;
   runerror(word(-k));
   end;
gotoxy(0,wherey-1); clreol;
write(s,'=',res:0:3);
readln;
end.
Есть функции sin(a), cos(a), ln(a), exp(a), sqr(a), sqrt(a), pi(), log(a;b).
Коды ошибок
0 Успешно завершено
1 Слишком много операций и (или) скобок
2 Превышена вложенность скобок
3 Закрывающих скобок больше, чем открывающих
4 Неизвестная функция
5 Неверное количество аргументов фугкции [ver5+]
6 ОЧЕНЬ длинное число
7 Слишком большое число
8 Открывающих скобок больше, чем закрывающих
9 Ошибка в выражении
10 Слишком сложное выражение
11 Ошибка в выражении
12 Ошибка в выражении
13 Ошибка в выражении [ver5+]
14 Ошибка в выражении

0 Успешно завершено
1 Верхнее переполнение стека 0 при чтении
2 Верхнее переполнение стека br
3 Нижнее переполнение стека br
4 Неизвестная функция
5 par<>parcount[f]
6 Переполнение буфера ts
7 Ошибка преобразования числа
8 Стек br не пуст после чтения
9 Странный символ в выражении
10 Верхнее переполнение стека 1 или 2
11 Нижнее переполнение стека 0 при выполнении операции
12 n<>1 после вычисления выражения
13 Что-то с точками с запятой
14 Значение lst не соответствует типу элемента
1
Форумчанин Паскаля
 Аватар для code-n'-help
77 / 90 / 55
Регистрация: 08.11.2013
Сообщений: 399
Записей в блоге: 2
13.03.2014, 09:31  [ТС]
Pascal
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
Function ConvertStr(S:string):integer;
var  i:byte; r:integer;
begin
  r:=1;
  for i:=1 to length(s) do
  begin
  if i=1 then begin
    case s[i] of
    '9':r:=9;
    '8':r:=8;
    '7':r:=7;
    '6':r:=6;
    '5':r:=5;
    '4':r:=4;
    '3':r:=3;
    '2':r:=2;
    '1':r:=1;
    end;
  end;
  if i>1 then begin
    case s[i] of
    '9':r:=r*10+9;
    '8':r:=r*10+8;
    '7':r:=r*10+7;
    '6':r:=r*10+6;
    '5':r:=r*10+5;
    '4':r:=r*10+4;
    '3':r:=r*10+3;
    '2':r:=r*10+2;
    '1':r:=r*10+1;
    '0':r:=r*10;
    end;
  end;
  end;
if length(s)>0
then Convertstr:=r;
end;
 
 
var str,number:string;
    i,cnum,csym,j:word;
    Mnum,Msym:set of char;
    Arrsym:array [1..100] of char;
    Arrnum:array [1..100] of extended;
begin
cnum:=1;
csym:=1;
fillchar(arrnum,sizeof(arrnum),0);
Mnum:=['0'..'9'];
Msym:=['+','-','*','/','='];
readln(str);
number:='';
str:=str+'=';
for i:=1 to length(str)-1 do
  begin
    if (str[i] in Mnum)
    then begin
    number:=number+str[i];
    if (str[i+1] in Msym)
    then begin
      ArrNum[cnum]:=convertstr(number);
      inc(cnum);
      number:='';
    end;
    end
    else if (str[i] in Msym)
         then begin
         ArrSym[Csym]:=str[i];
         inc(csym);
         end;
  end;
dec(cnum);
dec(csym);
i:=1;
while i<=csym do
  begin
    if Arrsym[i]='*'
    then begin
      Arrnum[i]:=Arrnum[i]*Arrnum[i+1];
      for j:=i+1 to cnum do
        Arrnum[j]:=Arrnum[j+1];
      for j:=i to csym do
        Arrsym[j]:=arrsym[j+1];
    end
    else if Arrsym[i]='/'
    then begin
      Arrnum[i]:=Arrnum[i]/Arrnum[i+1];
      for j:=i+1 to cnum do
        Arrnum[j]:=Arrnum[j+1];
      for j:=i to csym do
        Arrsym[j]:=arrsym[j+1];
    end
    else inc(i);
end;
i:=1;
while i<=cnum do
begin
    if Arrsym[i]='+'
    then begin
      Arrnum[i]:=Arrnum[i]+Arrnum[i+1];
      for j:=i+1 to cnum do
        Arrnum[j]:=Arrnum[j+1];
      for j:=i to csym do
        Arrsym[j]:=arrsym[j+1];
    end
    else if Arrsym[i]='-'
    then begin
      Arrnum[i]:=Arrnum[i]-Arrnum[i+1];
      for j:=i+1 to cnum do
        Arrnum[j]:=Arrnum[j+1];
      for j:=i to csym do
        Arrsym[j]:=arrsym[j+1];
    end
    else inc(i);
end;
 
writeln('Resultat-->',Arrnum[1]:5:4);
end.
Добавлено через 40 секунд
а вот мой код но только он читает все ариф действия 4 видов +-*/
0
354 / 135 / 28
Регистрация: 16.12.2012
Сообщений: 607
Записей в блоге: 1
14.03.2014, 07:10
ConvertStr(S:string):integer;
Есть две стандартные..

И сразу r := 0.. и потом r := r*10+Ord(s[i]) - Ord('0'); не проще?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.03.2014, 07:10
Помогаю со студенческими работами здесь

Идея
Добрый день. Появилась идея создать устройство, для определенных целей (каких—сказать не могу, так как идея не имеет патента), которое...

Идея
Поцоны, чё теперь делать? Интересно, а можно ли сделать сайт, который будет действительно уникальным и востребованным. Тоесть не...

Идея
Здравствуйте, форумчане! :) У меня появилась интересная идея! Я хочу, чтобы мы создали социальный сайт или что-то в этом роде. Если это...

ИДЕЯ!
Добавились бы вы в каталог (чёрный), но что бы не размешать обратку там нужно заплатить 10 центов (всего)? Вам выгода - +1 обратка,...

comboBox Идея!!!
Всем привет !!! ПОмогите пожалуйсто радилась идея а реализовать её я не могу...:cry: 1- Мне надо чтобы был список в comboBox1 и при...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
Программный отбор элементов справочника 1С
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru