
ПОМОЩЬ по: Информатике
- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
Помогите, кто-нибудь! Задачу задали, на Паскале на тему "стеки". Написать программу для вычисления выражения из многозначных(однозначных включительно) чисел в постфиксной польской записи...
Написала сама программу, но она работает только при одной операции за раз, т.е. одно действие совершает... Кто возьмется помочь,(надеюсь такие найдутся), могу, если нужно выложить код своей недоделанной программы

- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
Мессалина
Так а в чём сложность? Нужно просто в стек записывать вложенные действия, чтобы не только одно работало.
Выкладывай код, я помогу. Причём лучше, чтобы ты разбиралась, будем пытаться обсуждать программу в форме диалога, чтобы ты не просто списала, а ещё и разобралась, как такое делать.
Так а в чём сложность? Нужно просто в стек записывать вложенные действия, чтобы не только одно работало.
Выкладывай код, я помогу. Причём лучше, чтобы ты разбиралась, будем пытаться обсуждать программу в форме диалога, чтобы ты не просто списала, а ещё и разобралась, как такое делать.


program zapis;
type pt=^el;
el=record
data:real;
next:pt;
end;
mas=array[1..255] of integer;
Var s:string;
f:boolean;
rez,r:real;
ri:mas;
i,m,k:integer;
Procedure ReadStack (var u:pt; var dig:real);
var x:pt;
begin
dig:=u^.data; x:=u;
u:=u^.next; dispose(x);
end;
procedure WriteStack (var u:pt; dig:real);
var x:pt;
begin
new(x);
x^.data:=dig; x^.next:=u;
u:=x;
end;
function free(u:pt):boolean; {proverka na to, pustoj li stek}
begin
if u=nil then free:=false
else free:=true;
end;
procedure operation (ch:char; a,b:real; var c:real); {sobstvenno dejstvija}
begin
case ch of
'+':c:=a+b;
'-':c:=b-a;
'*':c:=a*b;
'/':c:=b/a;
end;
end;
Procedure solve (a:string; Var pp:boolean; var z:real); {osnovnaja procedura}
var head:pt;
i,k:integer;
r,w:real;
s:string;
begin
s:='';
head:=nil; pp:=true;
i:=1;
while (i<length(a)) and pp do
begin s:='';
while a<>' ' do {4itaem zifru}
begin
if not (a in ['+','-','*','/',' ']) then
s:=s+a;
i:=i+1;
end;
if a=' ' then i:=i+1; {propuskaem probelu}
val(s,r,k); { k=0 esli preobrazovenie simvolov v zifru prowlo uspewno}
if k=0 then writestack(head,r)
else pp:=false;
if a in ['+','-','*','/'] then
begin begin
if free(head) then readstack(head,r)
else pp:=false;
end;
begin
if free(head) then readstack(head,w)
else pp:=false;
end;
if pp then
begin
if a=' ' then i:=i+1;
operation(a,r,w,r);
writestack(head,r);
end;
end;
end;
readstack(head,z);
end;
Begin
writeln('Vvedite stroku v formate 4islo probel 4islo probel znak (4 4 +) ');
readln(s);
if s<>'' then
begin
solve(s,f,rez);
if f then writeln(rez:6:2)
else writeln('varazhenie ne mozhet but vu4isleno');
end
else writeln ('stroka pusta');
readln;
end.
Вот собственно код
type pt=^el;
el=record
data:real;
next:pt;
end;
mas=array[1..255] of integer;
Var s:string;
f:boolean;
rez,r:real;
ri:mas;
i,m,k:integer;
Procedure ReadStack (var u:pt; var dig:real);
var x:pt;
begin
dig:=u^.data; x:=u;
u:=u^.next; dispose(x);
end;
procedure WriteStack (var u:pt; dig:real);
var x:pt;
begin
new(x);
x^.data:=dig; x^.next:=u;
u:=x;
end;
function free(u:pt):boolean; {proverka na to, pustoj li stek}
begin
if u=nil then free:=false
else free:=true;
end;
procedure operation (ch:char; a,b:real; var c:real); {sobstvenno dejstvija}
begin
case ch of
'+':c:=a+b;
'-':c:=b-a;
'*':c:=a*b;
'/':c:=b/a;
end;
end;
Procedure solve (a:string; Var pp:boolean; var z:real); {osnovnaja procedura}
var head:pt;
i,k:integer;
r,w:real;
s:string;
begin
s:='';
head:=nil; pp:=true;
i:=1;
while (i<length(a)) and pp do
begin s:='';
while a<>' ' do {4itaem zifru}
begin
if not (a in ['+','-','*','/',' ']) then
s:=s+a;
i:=i+1;
end;
if a=' ' then i:=i+1; {propuskaem probelu}
val(s,r,k); { k=0 esli preobrazovenie simvolov v zifru prowlo uspewno}
if k=0 then writestack(head,r)
else pp:=false;
if a in ['+','-','*','/'] then
begin begin
if free(head) then readstack(head,r)
else pp:=false;
end;
begin
if free(head) then readstack(head,w)
else pp:=false;
end;
if pp then
begin
if a=' ' then i:=i+1;
operation(a,r,w,r);
writestack(head,r);
end;
end;
end;
readstack(head,z);
end;
Begin
writeln('Vvedite stroku v formate 4islo probel 4islo probel znak (4 4 +) ');
readln(s);
if s<>'' then
begin
solve(s,f,rez);
if f then writeln(rez:6:2)
else writeln('varazhenie ne mozhet but vu4isleno');
end
else writeln ('stroka pusta');
readln;
end.
Вот собственно код
- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
Мессалина
Я привёл код программы к человеческому виду и исправил.
Могу сказать следующее: я убрал лишние переменные, которые не использовались, существенно исправил процедуру solve и немного operation (левый операнд a, правый b (из стека читаем в обратном порядке, поэтому логичнее в вызове параметры поменять местами)) и основную программу (нужно добавить пробел к введённой строке, так проще).
Логика процедуры solve простая. Сначала пропускаем пробелы. Потом мы в цикле идём по строке (кстати не нужно до этого цикла ничего присваивать в переменную s) и делаем следующее: если цифра, то читаем число, пропускаем пробелы и пишем это число в стек, если операция, то читаем два числа из стека и делаем операцию (числа из стека прочитались в обратном порядке, поэтому параметры для операции наоборот), пишем результат в стек, сдвигаемся на следующий символ (тут как раз может пригодиться тот самый пробел, который мы добавили к прочитанной строке, в случае, если это последняя операция и последний символ введённой строки) и пропускаем пробелы, если не цифра и не операция, то ошибочный символ. В конце читаем из стека ответ.
Кстати, я уже не стал менять, но обычно стараются писать покороче. Можешь подумать над следующим: функцию free можно написать в одну строчку
Разбирайся, задавай вопросы. Надеюсь, помог.
Я привёл код программы к человеческому виду и исправил.
Код: Выделить всё
program Linux_forever; {Copyright Linux_forever (c) 2008}
type pt = ^el;
el = record
data : real;
next : pt;
end;
var s : string;
f : boolean;
rez : real;
procedure ReadStack(var u : pt; var dig : real);
var x : pt;
begin
dig := u^.data;
x := u;
u := u^.next;
dispose(x);
end;
procedure WriteStack(var u : pt; dig : real);
var x : pt;
begin
new(x);
x^.data := dig;
x^.next := u;
u := x;
end;
function free(u : pt) : boolean; {Проверка стека на пустоту}
begin
if u = nil then
free := false
else
free := true;
end;
procedure operation(ch : char; a, b : real; var c : real); {Операции}
begin
case ch of
'+':
c := a + b;
'-':
c := a - b;
'*':
c := a * b;
'/':
c := a / b;
end;
end;
procedure solve(a : string; var pp : boolean; var z : real); {Основная процедура}
var head : pt;
op : char;
i, k : integer;
r, w : real;
s : string;
begin
head := nil;
pp := true;
i := 1;
while (i < length(a)) and pp do
begin
s := '';
if a[i] in ['0'..'9'] then {Если число}
begin
while a[i] in ['0'..'9'] do {Читаем число}
begin
s := s + a[i];
i := i + 1;
end;
while a[i] = ' ' do {Пропускаем пробелы после числа}
i := i + 1;
val(s, r, k); {k = 0, если преобразование символов в число прошло успешно}
if k = 0 then
writestack(head, r) {Сохраняем число в стек}
else
pp := false;
end
else if a[i] in ['+', '-', '*', '/'] then {Если операция}
begin
op := a[i]; {Запоминаем операцию}
i := i + 1; {Сдвигаемся дальше по строке}
while a[i] = ' ' do {Пропускаем пробелы после операции}
i := i + 1;
if free(head) then
readstack(head, r) {Читаем второе число из стека}
else
pp := false;
if free(head) then
readstack(head, w) {Читаем первое число из стека}
else
pp := false;
if pp then
begin
operation(op, w, r, r); {Делаем операцию w r op}
writestack(head, r); {Результат операции сохраняем в стек}
end;
end
else {Если не число и не операция}
pp := false;
end;
if free(head) then
readstack(head,z) {Читаем результат из стека}
else
pp := false;
end;
Begin
writeln('Введите строку в формате: число пробел число пробел знак (4 4 +)');
readln(s);
if s <> '' then
begin
s := s + ' ';
solve(s, f, rez);
if f then
writeln(rez:6:2)
else
writeln('Выражение не может быть вычислено');
end
else
writeln ('Строка пуста');
readln;
end.
Логика процедуры solve простая. Сначала пропускаем пробелы. Потом мы в цикле идём по строке (кстати не нужно до этого цикла ничего присваивать в переменную s) и делаем следующее: если цифра, то читаем число, пропускаем пробелы и пишем это число в стек, если операция, то читаем два числа из стека и делаем операцию (числа из стека прочитались в обратном порядке, поэтому параметры для операции наоборот), пишем результат в стек, сдвигаемся на следующий символ (тут как раз может пригодиться тот самый пробел, который мы добавили к прочитанной строке, в случае, если это последняя операция и последний символ введённой строки) и пропускаем пробелы, если не цифра и не операция, то ошибочный символ. В конце читаем из стека ответ.
Кстати, я уже не стал менять, но обычно стараются писать покороче. Можешь подумать над следующим: функцию free можно написать в одну строчку
Код: Выделить всё
function free(u : pt) : boolean; {Проверка стека на пустоту}
begin
free := (u <> nil);
end;


ОГОГО!!!!
Спасибо огромное, только вот мне не понятно где у меня ошибка была... Или там везде была ошибка в solve? =((
Это все не я, а Окулов. В учебнике т.е. так было, а я не стала менять ничего, что вроде бы как работало... Кстати, ты вот комментарии на русском пишешь, т.е. в паскале у тебя кириллица поддерживается? Как это сделать можно, подскажи пожалуйста?

Кстати, я уже не стал менять, но обычно стараются писать покороче
Это все не я, а Окулов. В учебнике т.е. так было, а я не стала менять ничего, что вроде бы как работало... Кстати, ты вот комментарии на русском пишешь, т.е. в паскале у тебя кириллица поддерживается? Как это сделать можно, подскажи пожалуйста?

- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
Мессалина
Пожалуйста.
Мне трудно сказать, где именно была ошибка в solve, потому что там было примерно всё по делу, но исправлять пришлось много чего. Можешь просто сравнить мой код со своим и изучать отличия (solve пришлось существенно исправить).
Ну, я из учебников ничего не переписывал, я просто предложил убедиться, что моя одна строчка эквивалентна тем нескольким строчкам, которые у тебя были.
Конечно, я комментарии на русском пишу. Чтобы тебе понятнее было. А для себя обычно по-английски пишу, лень язык переключать.
Фраза "поддерживается кириллица в Паскале" звучит крайне странно. Она основана на неправильном представлении о том, что такое код программы и что с ним делать, чтобы получить программу. Так вот код программы - это не что-то страшное и секретное или закодированное, а обычный текст. Программу можно писать не только в синем окошке досовского эмулятора, а можно писать в ЛЮБОМ текстовом редакторе, например в блокноте или вообще в Vim в Linux (что я и делал). Потом эту программу нужно откомпилировать КОМПИЛЯТОРОМ языка Паскаль и запускать на выполнение (и можно ещё тестировать). Поэтому поддержка или не поддержка кириллицы - ПОЛНАЯ ГЛУПОСТЬ. Разве нельзя в текстовом файле написать русские буквы? Можно! Вот я и написал. Меняешь язык и пишешь. Самое худшее, что может быть, несоответствие кодировок. Исправить можно только одним способом - поменять кодировку файла.
Поэтому не нужно ничего плохого думать о программе на Паскале. ЭТО ТЕКСТОВЫЙ ФАЙЛ, только с суффиксом в имени не .txt (как обычно пишут в Windows), а с суффиксом .pas и ничего больше. Это всего лишь условность.
В любом случае, если лень менять язык, кодировку или редактор, можно писать по-английски (желательно без ошибок
).
Вопросы по программе есть? Или всё просто и понятно?
Пожалуйста.
Мне трудно сказать, где именно была ошибка в solve, потому что там было примерно всё по делу, но исправлять пришлось много чего. Можешь просто сравнить мой код со своим и изучать отличия (solve пришлось существенно исправить).
Ну, я из учебников ничего не переписывал, я просто предложил убедиться, что моя одна строчка эквивалентна тем нескольким строчкам, которые у тебя были.
Конечно, я комментарии на русском пишу. Чтобы тебе понятнее было. А для себя обычно по-английски пишу, лень язык переключать.
Фраза "поддерживается кириллица в Паскале" звучит крайне странно. Она основана на неправильном представлении о том, что такое код программы и что с ним делать, чтобы получить программу. Так вот код программы - это не что-то страшное и секретное или закодированное, а обычный текст. Программу можно писать не только в синем окошке досовского эмулятора, а можно писать в ЛЮБОМ текстовом редакторе, например в блокноте или вообще в Vim в Linux (что я и делал). Потом эту программу нужно откомпилировать КОМПИЛЯТОРОМ языка Паскаль и запускать на выполнение (и можно ещё тестировать). Поэтому поддержка или не поддержка кириллицы - ПОЛНАЯ ГЛУПОСТЬ. Разве нельзя в текстовом файле написать русские буквы? Можно! Вот я и написал. Меняешь язык и пишешь. Самое худшее, что может быть, несоответствие кодировок. Исправить можно только одним способом - поменять кодировку файла.
Поэтому не нужно ничего плохого думать о программе на Паскале. ЭТО ТЕКСТОВЫЙ ФАЙЛ, только с суффиксом в имени не .txt (как обычно пишут в Windows), а с суффиксом .pas и ничего больше. Это всего лишь условность.
В любом случае, если лень менять язык, кодировку или редактор, можно писать по-английски (желательно без ошибок

Вопросы по программе есть? Или всё просто и понятно?


Да нет, я прекрасно знаю, что можно в любом текстовом редакторе это все делать. Другое дело, что неудобно, если комментарии на русском, потом пытаться отлаживать программу именно в среде Паскаля, т.к. там кракозябра получается. У нас в школе, пока еще сервак не полетел, как-то умудрились лаборанты сделать, чтобы русский язык кракозяброй не высвечивался. А вот теперь такого нет, что очень и очень жалко, т.к. учительница комментарии на английском может не понять, а транслитом я пишу не совсем обычно (думаю, ты заметил) =)
- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
Мессалина
Я трансит вообще не уважаю. И никогда так не пишу.
Язык переключаться должен. Кракозябры получаются из-за неправильной кодировки. Пересохрани файл в нужную кодировку и будет всё нормально.
cp1251 - кодировка Windows
cp866 - кодировка DOS (для Паскаля подойдёт)
А я вообще в Linux использую кодировку utf8 и никаких проблем не испытываю.
И не нужно жаловаться на кого-то или на серверы, если не знаете как менять кодировки и переключать языки. Это всё возможно сделать. Я вообще не понял, в чём проблема состоит.
Что не получается?
Я трансит вообще не уважаю. И никогда так не пишу.
Язык переключаться должен. Кракозябры получаются из-за неправильной кодировки. Пересохрани файл в нужную кодировку и будет всё нормально.
cp1251 - кодировка Windows
cp866 - кодировка DOS (для Паскаля подойдёт)
А я вообще в Linux использую кодировку utf8 и никаких проблем не испытываю.
И не нужно жаловаться на кого-то или на серверы, если не знаете как менять кодировки и переключать языки. Это всё возможно сделать. Я вообще не понял, в чём проблема состоит.
Что не получается?


- Linux forever!
- Втянувшийся
- Сообщения: 425
- Зарегистрирован: Сб май 31, 2008 7:59 pm
- Откуда: Харьков, Украина / Москва, РФ
- Контактная информация:
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость