Помощь - Поиск - Пользователи - Календарь
Полная версия: Стек.Польская запись.Вычисление значения.
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Бунтарь
Здравствуйте! Подскажите как разобрать всю кашу %%)
Просмотрел все темы форума, но всё не то...

Исходное условие задания:

Написать программу, вычисления значения выражения представленного в виде польской записи (постфиксной записи). Выражение состоит из цифр от 1 до 9 и знаков операций.(к примеру (a+b)*c в выражение ab+c*). Просматривая строку, анализируем очередной символ, если это: - цифра, то записываем её в стек; - то читаем 2 элемента из стека, выполняем математическую операцию, определяемую этим знаком, и заносим результат в стек. После просмотра всей строки в стеке должен оставаться один элемент, он и является решением задачи. (Процедура Val (s,x,k) преобразует символьное представление цифры s в соответствующее числовое значение. При этом k=0, если такое преобразование возможно, в противном случаи k>0)


Задачу нужно реализовать в динамике, я реализовал в статике (массивы), помогите с динамикой - не знаю как.


А теперь что у меня получилось ( в статике):
Uses CRT;

{Вычисление значения выражения.Сначала скобочное выражение преобразуется в польскую (постфиксную) запись}

Const OperSet:set of char= ['+','-','*','/','(',')','^'];

Var Stack : array [1..10] of Char;
InputString : String;
OutputString : String;
I,J,K, TopStack : Word;
Symb : Char;
Temp : Char;
Variable, VarStack : array [1..10] Of Real;
Result, Op : Real;

Function Calc(Op1, Op2 : Real; Op : Char):Real;
Var Result : Real;
Begin
Case Op Of
'+':Result := Op1 + Op2;
'-':Result := Op1 - Op2;
'*':Result := Op1 * Op2;
'/':Result := Op1 / Op2;
End;
Calc := Result;
End;


Function ChToInt(C:Char):Integer;
Var Result : Integer;
Begin
Case C Of
'-': Result := 1;
'+': Result := 1;
'*': Result := 2;
'/': Result := 2;
End;
ChToInt := Result;
End;

Function PRCD(Ch1, Ch2 : Char):Boolean;
Var Result : Boolean;
Begin
If ChToInt(Ch1) >= ChToInt(Ch2) Then Result := True
Else Result := False;

If Ch2='(' Then Result := False;
If Ch1='(' Then Result := False;
If (Ch2=')') And (Ch1<>'(') Then Result := True;
If (Ch2='(') And (Ch1=')') Then Result := False;

PRCD := Result;
End;

Procedure Push(Ch : Char);
Begin
Inc(TopStack);
Stack[TopStack] := Ch;
End;

Function Pop:Char;
Begin
Pop := Stack[TopStack];
Stack[TopStack] := ' ';
Dec(TopStack);
End;

Begin
ClrScr;
TopStack := 0;
OutputString := '';

Write('‚ўҐ¤ЁвҐ ўла ¦Ґ­ЁҐ: ');
ReadLn(InputString);

For I := 1 To 10 Do Stack[I] := ' ';
For I := 1 To 10 Do Variable[I] := 0;
For I := 1 To 10 Do VarStack[I] := 0;

For I := 1 To Length(InputString) Do Begin
Symb := InputString[I];
If Symb IN OperSet Then Begin
While (TopStack <> 0) And PRCD(Stack[TopStack],Symb) Do Begin
Temp := Pop;
OutputString := OutputString + Temp;
End; { while }
If (TopStack = 0) Or (Symb<>')') Then Push(Symb)
Else Temp := Pop;

End Else OutputString := OutputString + Symb;
End; { for }

While TopStack <> 0 Do Begin
Temp := Pop;
OutputString := OutputString + Temp;
End;

WriteLn(InputString);
WriteLn(OutputString);

K := 0;
For I := 1 To Length(OutputString) Do Begin
If Not(OutputString[I] IN OperSet) Then Begin
Inc(K);
Write('Input value of ',OutputString[I],' = ');
ReadLn(Variable[K]);
End; { if }
End; { for }

K := 0;
Result := 0;
TopStack := 0;

For I := 1 To Length(OutputString) Do Begin
If OutputString[I] IN OperSet Then Begin
If TopStack = 1
Then Result := Calc(0,VarStack[TopStack],OutputString[I])
Else Begin
VarStack[TopStack-1] := Calc(VarStack[TopStack-1],VarStack[TopStack],OutputString[I]);
VarStack[TopStack] := 0;
Dec(TopStack);
Result := VarStack[TopStack];
End;
End Else Begin
Inc(K);
Inc(TopStack);
VarStack[TopStack] := Variable[K];
End; { if }
End; { for }

WriteLn(Result:2:0);
ReadLn;
End.
[code]
volvo
Цитата
помогите с динамикой - не знаю как.
Реализовать стек не с использованием массива, а с использованием динамической памяти.
Цитата
Просмотрел все темы форума
Значит, не все темы просмотрел... Есть же задача, вычисляющая значение постфиксного выражения:
Задача на Обратную Польскую Нотацию (постфикс)
Оттуда можешь взять реализацию стека в динамике. Замени свою реализацию Push/Pop на приведенные по ссылке - будет у тебя динамика (если, конечно, где-то в программе еще не используется обращение напрямую к массиву, заменяющему стек... Если используется - меняй на работу через функции)
TarasBer
Для динамики стек придётся реализовывать так:


type
PStack = ^TStack;

TStack = record
value: real;
Next: PStack;
end;

var
R: PStack;

procedure Push(var R: PStack; aValue: real);
var
tmp: PStack;
begin
// заводим новый элемент связного списка, ставим ему значение и связь с предыдущим элементов, передвигаем голову списка
New(tmp);
tmp.Value := aValue;
tmp.Next := R;
R := tmp;
end;

извлечение из стека аналогично



volvo опередил
volvo
Еще желающие зайти и продублировать способ реализации есть?
TarasBer
Я открыл страницу (твоего поста ещё не было) и отошёл на 20 минут, потом вернулся, написал ответ. За эти 20 минут в теме, оказывается, многое изменилось.
Короче, удали мой пост.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.