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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.04.2010, 12:12   #1
Nelson1992
Пользователь
 
Регистрация: 24.11.2009
Сообщений: 30
По умолчанию Преобразование арифметического выражения из инфиксной в постфиксную форму записи

Помогите реализовать алгоритм I-P на Pascal...Для работы со стеком использовать связное распределение памяти процедуры:
- Создание пустого стека
- Добавление элемента на вершину стека
- Удаление элемента с вершины стека
Доработать алгоритм I-P, обеспечив обработку арифметических выражений, содержащих скобки.Запрограммировать доработанный алгоритм на языке Паскаль.


I-P1. [инициализация] Проинициализировать стек STORE , строку «Постфикс»
I-P2. [читать символ] Прочитать «символ» из входной строки «Инфикс»
I-P3. [операнд?] Если прочитанный «символ» – переменная, добавить «символ» в конец выходной строки «Постфикс»
I-P3. [операция?] Если прочитанный «символ» – операция
I-P4. [стек пуст?] Если стек STORE пуст, добавить «символ» на вершину стека STORE.
I-P5. [стек не пуст?] Если стек STORE не пуст, сравнить приоритеты «символ» и элемента на вершине STORE
Если приоритет элемента на вершине STORE больше приоритета «символ», снять элемент с вершины STORE и добавить к концу строки «Постфикс»
Иначе, поместить «символ» на вершину STORE
→ I-P4
I-P6. [следующий символ?] Если остались непрочитанные символы, → I-P2
I-P7. [вывести из стека] Снимать элемент с вершины STORE и добавлять в конец «Постфикс» до состояния НЕХВАТКА
I-P8. [результат] Вывести строку «Постфикс»
Nelson1992 вне форума Ответить с цитированием
Старый 29.05.2021, 16:51   #2
canadamoscow
Пользователь
 
Аватар для canadamoscow
 
Регистрация: 16.05.2020
Сообщений: 57
По умолчанию

Видеоурок: Калькулятор со скобками
Код:
function SplitExpr(self: string): sequence of string; extensionmethod;
begin //коррекция строки и разделение её по  операциям и операндам
  var s := self.replace(' ', ''); //self = -3 + 2( -4 + 1)   >>  -3+2(-4+1)  >>
  if s[1] = '-' then s := '0'+ s; // 0-3+2(-4+1)  >>
  s := s.replace('(-', '(0-');    // 0-3+2(0-4+1) >>
  s := s.RegexReplace('\d\(', t -> t.toString[1]+'*('); // 0-3+2*(0-4+1)
  var sb := '';
  foreach var ch in s do
    if ch in '()+-*/' then
     begin
        if sb.Length<>0 then yield sb; //Result += Arr(sb)
        sb := '';
        yield ch //Result += Arr(ch)
     end 
    else sb := sb + ch;
  if sb.Length<>0 then yield sb //Result += Arr(sb)
end;

function ToPostfix(self: sequence of string):sequence of string; extensionmethod;
begin
  var op := '()+-*/'; //приоритет операций зависит от индекса op.indexOf(operation) div 2 = 0,0,1,1,2,2
  var opStack := new Stack<string>;
  var postfixList := new List<string>;
 
  foreach var token in self do
   case token of
     '+','-','*','/': 
          begin //пока стек не пуст и приоритет операции на стеке больше равен приоритету текущей операции то
             while (opStack.Count>0) and (op.IndexOf(opStack.Peek) div 2 >= op.IndexOf(token) div 2) do
                postfixList.Add(opStack.Pop);
             opStack.Push(token);
          end;
     '(': opStack.Push(token);
     ')': begin
             while opStack.Peek <> '(' do postfixList.Add(opStack.Pop);
             opStack.Pop; //убираем '(' из opStack
          end
     else postfixList.Add(token); 
   end;        
    
  while opStack.Count <> 0 do postfixList.Add(opStack.Pop);
  Result := postfixList;
end;

function EvalExpr(self: sequence of string): real; extensionmethod;
begin //вычисление выражения из постфиксной формы
  var st := new Stack<real>;
  foreach var entr in self do
   case entr of
      '+':  st.Push(st.Pop + st.Pop);
      '-':  st.Push(- st.Pop + st.Pop);
      '*':  st.Push(st.Pop * st.Pop);
      '/':  begin var x:=st.Pop; st.Push(st.Pop / x) end
      else  st.Push(entr.ToReal);
   end;
  Result := st.Pop;
end;

begin
  '-1 - 2 - 2(-4+1)'
  .SplitExpr.Println //коррекция и разделение
  .ToPostfix.Println //вывражение в постфиксной форме
  .EvalExpr.Println;//вычисление выражения
 
  '(A+B)*(C-D) '
  .SplitExpr.Println
  .ToPostfix.Println
end.

Последний раз редактировалось canadamoscow; 30.05.2021 в 13:10.
canadamoscow вне форума Ответить с цитированием
Старый 29.05.2021, 18:04   #3
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,534
По умолчанию

Через 11 лет... Лучше поздно, чем никогда ?
digitalis вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вычисление условного арифметического выражения doda666 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 16.03.2010 08:02
программа для перевода из инфиксной формы записи в постфиксную Diana888 Помощь студентам 0 01.10.2009 23:15
программа для перевода из инфиксной формы записи в постфиксную Diana888 Общие вопросы C/C++ 0 01.10.2009 23:06
Построение арифметического выражения. Arugin Помощь студентам 5 16.03.2009 09:49