IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Вычисления выражени, Проблемка...
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Необходима помощь в задаче. Суть ее состоит в следующем: Необходимо с помощью рекурсии вычислить значение выражения, представленного в виде некоторого "константного выражения". То есть, вы вводим некоторую строку, и потом работаем с нем, вычисляя необходимое smile.gif
Примеры таких выражений: 24; 2*2+2; (634+45); ((7-121)*32)

Мой код получился следующим:
Uses Crt;

Var
str : string;
c,op: char;
x,y : integer;

{Подсчет значения выражения с помощью рекурсии}
{i - индекс соотв. символа}
{s - строка с выражением}
Function Res(i:integer; s:string):integer;
Begin
c:=s[i];
{Перевод в число целого типа}
if (c>='0') and (c<='9') then
Res:=Ord©-ord('0')
{Арифметические операции с операндами}
else
begin
x:=Res(i,s);
inc(i);
op:=s[i];
inc(i);
c:=s[i];
y:=Res(i,s);
case op of
'+': Res:=x+y;
'-': Res:=x-y;
'*': Res:=x*y;
end;
inc(i);
c:=s[i];
end;
End;

{Основная программа}
Begin
clrscr;
write('Исходное выражение: ');
readln(str);
writeln('Значение выражения: ',Res(1,str));
readkey;
End.


Сообщение отредактировано: Relrin -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


В общем, переделать чуть-чуть у меня не вышло, к сожалению.
Переделал дофига (то есть как бы делал я).

Вышло так:


{$APPTYPE CONSOLE}
var
str : string;

{Подсчет значения выражения с помощью рекурсии}
{s - строка с выражением}
function Value(S: string): longint;
var
i: integer;

Function Res(prior: integer):longint;
var
sign: boolean;
tmp_prior: integer;
r: integer; // сюда будем писать результат

function GetNumber: boolean; // возвращает, получилось ли взять число
var
start_i: integer;
begin
start_i := i;
result := false;
r := 0;
sign := false;
if i <= Length(s) then case s[i] of
'-' : begin
// минус перед числом
sign := true;
inc(i);
end;
'+' : begin
// плюс перед числом
sign := false;
inc(i);
end;
end;
while (i <= Length(s)) and (s[i] in ['0' .. '9']) do begin
// собираем число по цифрам
r := r * 10 + (ord(s[i]) - ord('0'));
result := true;
inc(i);
end;
if sign then r:= -r;
if not result then i := start_i; // если не удалось взять число, возвращаем указатель на место
end;


Begin
{Перевод в число целого типа}
if GetNumber then
// взяли число, значит r стал какой надо, значит, всё в порядке
else if s[i] = '(' then begin
// рекурсивно разобрать то, что внутри скобки
inc(i);
r := Res(0);
if s[i] = ')' then inc(i); // а если нет, то это ошибка выражения
end;

tmp_prior := 0;
while (i <= Length(s)) do begin

case S[i] of
// определить приоритет текущей операции
'+': tmp_prior := 1;
'-': tmp_prior := 1;
'*': tmp_prior := 2;
'/': tmp_prior := 2;
else break;
end;

if tmp_prior < prior then break;
// тут и учитываетя приоритет операций!
// если приоритет новой операции ниже текущего, то надо выйти из рекурсии
// на уровень выше - пусть новую операцию обрабатывают на том уровне

case S[i] of
'+': begin
inc(i);
r := r + Res(tmp_prior);
end;
'-': begin
inc(i);
r := r - Res(tmp_prior);
end;
'*': begin
inc(i);
r := r * Res(tmp_prior);
end;
'/': begin
inc(i);
r := r div Res(tmp_prior);
end;
else break;
end;
end;
result := r;
End;

begin
i := 1;
Result := Res(0);
end;

{Основная программа}
Begin
write('Исходное выражение: ');
readln(str);
writeln('Значение выражения: ',Value(str));
readln;
End.



А общая теория тут: http://algolist.manual.ru/syntax/parsear.php


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Relrin   Вычисления выражени   8.04.2011 20:03
Гость   Во-первых, не Function Res(i:integer; s:string):i…   8.04.2011 20:33
Relrin   C приоритетами и скобками пока не очень могу предс…   8.04.2011 23:05
Гость   1. Перепиши определитель числа без библиотечного v…   8.04.2011 23:51
Relrin   Переделал, теперь берет и longint числа :good: Fu…   9.04.2011 0:38
TarasBer   В общем, переделать чуть-чуть у меня не вышло, к с…   9.04.2011 0:55
Relrin   За помощь! Пока читаю "теорию"+разби…   9.04.2011 1:11
TarasBer   > До этого пару раз проверил пару примеров, тип…   9.04.2011 1:18
Relrin   Ошибка найдена! Вот это: if GetNumber then …   9.04.2011 1:48
TarasBer   Не верю. (634+45) работает в моём варианте. В моём…   9.04.2011 1:55
Relrin   Не верю. (634+45) работает в моём варианте. В моё…   9.04.2011 2:04
TarasBer   Ты покажи выражение, которое НЕ работает в моём ва…   9.04.2011 2:10
Relrin   Ты покажи выражение, которое НЕ работает в моём в…   9.04.2011 2:17
TarasBer   > В изначальном варианте, у меня не работает ва…   9.04.2011 2:24
Relrin   Да ты просто походу пробел в начале выражения пос…   9.04.2011 2:44
TarasBer   Значит, что-то не то сделал с моим кодом. Судя по…   9.04.2011 2:47


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 5.05.2024 12:05
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name