Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.05.2012, 14:05   #1
АлексВ
 
Регистрация: 18.05.2012
Сообщений: 6
По умолчанию Вопросы по обратной польской записи

Здраствуйте! Мне было поручено задание создать программу, которая переводит выражение в ОПЗ и находит его значение. Первую часть задания я выполнил, во второй же находит неверный результат, если числа дво- и более значные. Поэтому у меня возникло несколько небольших вопросов. Буду очень признателен за помощь.
1) Возможна ли реализация алгоритма для двозначных и более чисел? Во всех примерах создания ОПЗ, которые я видел, действия проводились над однозначными (например (6+8)*(7-3) : 6 8 + 7 3 - *)
2) Подскажите, если ли способ считывания двух и более последовательных числовых символов в string'е как одного числа? Если есть, каким способом его можно реализовать?
3) В самой ОПЗ, нужно ли делать пробелы между отдельными цифрами и знаками? Если переводить их в стеки (array [1..100] of real) или присваивать значения переменных (a,b,c,d,e... вместо цифр) и вписывать значения с клавиатуры , то в первом случае, если считывается пробел, выкидывает ошибку в работе программы, во втором оно считает пробелы тоже переменными и требует ввести их значения.
АлексВ вне форума Ответить с цитированием
Старый 18.05.2012, 14:14   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

1) да ( в примерах берутся однозначные просто для экономии).
2) s:='2+23+77';
n:=strtoint( copy(s, 3, 2) );
3) а пробел это что оператор действия или значение? Если он нужен для вычислений, то ДА в противном случае НЕТ.
программа — запись алгоритма на языке понятном транслятору
evg_m на форуме Ответить с цитированием
Старый 18.05.2012, 16:38   #3
АлексВ
 
Регистрация: 18.05.2012
Сообщений: 6
Восклицание

Проверил, но все равно не хочет работать с двозначными и более цифрами и пробелами. Вот код моей программы, подскажите, что нужно исправить, чтобы убрать эти недостатки.
Код:
Program PPZ;
const
    oper1=['+','-'];
    oper2=['*','/'];
    symbol=['a'..'z','A'..'Z','0'..'9','.'];
var
    Stack: array [1..100] of real;
    i,j,m,c: integer;
    s :char;
    eb,ea :string;
    r: real;
    p :word;
    
procedure findsym;
begin
    while (p<=length(eb)) and(eb[p] in [#32, #9]) do
        p:=p+1;
    if p>length(eb) then
        s:=#0
    else
    begin
        s:=eb[p];
        p:=p+1;
    end;
end;

procedure expression;
forward;

procedure get_var;
begin
    
    while s in symbol do
    begin
        ea:=ea+s;
        findsym
    end
end;

procedure term;
var a:char;
begin
    if s='(' then
    begin
        findsym;
        expression;
        findsym
    end
        else
        get_var;
    while s in oper2 do
    begin
        
        a:=s;
        findsym;
        term;
        ea:=ea+a
    end
end;

procedure expression;
var a:char;
begin
    if s='+' then
        findsym
    else if s='-' then
    begin
        a:='-';
        findsym
    end
        else
        a:=#32;
    term;
    if a='-' then ea:=ea+' (-)';
    
    while s in oper1 do
    begin
        a:=s;
        findsym;
        term;
        ea:=ea+a
    end
end;

{Main part}
begin

    writeln ('Input expression');
    readln (eb);
    
    p:=1;
    findsym;
    expression;
    writeln('Start expression: ',eb);
    writeln(ea);
    
    m:=1;
     for i:=1 to length(ea) do begin
         if ea[i]=('+') then begin
            r:=(stack[m-2])+(stack[m-1]);
            stack[m-2]:=r;
            m:=m-1
                             end
         else
             if ea[i]=('-') then begin
                r:=(stack[m-2])-(stack[m-1]);
                stack[m-2]:=r;
                m:=m-1
                                 end
             else
                 if ea[i]=('*') then begin
                    r:=(stack[m-2])*(stack[m-1]);
                    stack[m-2]:=r;
                    m:=m-1
                                     end
                 else
                      if ea[i]=('/') then begin
                         r:=(stack[m-2])/(stack[m-1]);
                         stack[m-2]:=r;
                         m:=m-1
                                          end


                                 else  begin
                                      c:= StrToInt (ea[i]);
                                      j:=c;
                                       stack[m]:=j;
                                       m:=m+1;
                                       end
                                  end;

     write('Значение выражения (',ea,') равно:',stack[1]);
     
readln;
end.
АлексВ вне форума Ответить с цитированием
Старый 19.05.2012, 08:04   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
Код:
 else  begin
                                      c:= StrToInt (ea[i]);
                                      j:=c;
                                       stack[m]:=j;
                                       m:=m+1;
                                       end
                                  end;
Код:
else begin 
  cs:='';
  while ea[i] in ['0'..'9'] do begin cs:=cs+ea[i];
  stack[m]:=strtoint(cs);
  m:=m+1;
end;
P.S. var cs: string;
программа — запись алгоритма на языке понятном транслятору
evg_m на форуме Ответить с цитированием
Старый 19.05.2012, 09:36   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

добавлю. если интересно (полезно), то можете посмотреть на мою старинную библиотеку вычислений выражений на TurboPascal - ТУТ
Serge_Bliznykov вне форума Ответить с цитированием
Старый 20.05.2012, 00:58   #6
АлексВ
 
Регистрация: 18.05.2012
Сообщений: 6
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
Код:
else begin 
  cs:='';
  while ea[i] in ['0'..'9'] do begin cs:=cs+ea[i];
  stack[m]:=strtoint(cs);
  m:=m+1;
end;
P.S. var cs: string;
Вариант интересный, но в Pascal ABC (может просто в Turbo нужно?) пишет Ошибка: Параметр функции StrToInt не является целым числом(Program1.pas, строка 129). Думаю, это из-за того, что каждый раз ряд начинается с пробела, и не может переделать его в integer. Я пытался вводить удаление пробела, но не получилось.
АлексВ вне форума Ответить с цитированием
Старый 20.05.2012, 10:41   #7
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

А trim не подходит?
Код:
  stack[m]:=strtoint(trim(cs));
s-andriano вне форума Ответить с цитированием
Старый 21.05.2012, 16:59   #8
АлексВ
 
Регистрация: 18.05.2012
Сообщений: 6
По умолчанию

Всем спасибо, написал работающую для всех чисел и действий программу. Вопросы сняты.
АлексВ вне форума Ответить с цитированием
Старый 01.06.2012, 11:29   #9
Яна_М
Новичок
Джуниор
 
Регистрация: 01.06.2012
Сообщений: 1
Смущение

Цитата:
Сообщение от АлексВ Посмотреть сообщение
Всем спасибо, написал работающую для всех чисел и действий программу. Вопросы сняты.
А можешь скинуть весь код, пожалуйста? у меня такое же задание, но у меня вечно что-то не получается(
Яна_М вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Visual C++] Калькулятор с обратной польской нотацией WhiteKuz Visual C++ 0 22.03.2012 00:13
Форма обратной связи Cone PHP 9 07.12.2011 07:47
восстановление выражения по его прямой польской записи Котик Общие вопросы C/C++ 1 29.04.2010 22:30
Вопросы с HTML кодом форм обратной связи Michelle77 Помощь студентам 2 20.10.2009 15:47
преобразования польской формы записи уравнения Безбашик Общие вопросы по Java, Java SE, Kotlin 6 12.05.2009 10:25