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

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

> Задача на рекурсию
сообщение
Сообщение #1


Новичок
*

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

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


Помогите решить задачу на рекурсию. В строке записанно выражение следующего вида:
<формула>::=<индетификатор>/(<формула><знак><формула>)
<знак>::= +/-/*
<индетификатор>::=<буква>/<буква><цифра>
<цифра>::=0/1/2/3/4/5/6/7/8/9
Проверить правильность сочетания.
Не получается процедура проверки на истинность, может кто подскажет как это сделать. Вот мои наработки процедура ввода (скорее всего и там косяк есть).
Код

procedure TForm1.Button1Click(Sender: TObject);
type
tl=(form,buk,sko,skz,znak,cif);
var a:string[20];
i:integer;
begin
i:=1;
function read(var s:string; var i:integer):tl;
begin
  if s[i] in ['A'..'z'] then result:=buk;
  if s[i] in ['0'..'9'] then
   result:=cif
  else
   case s[i] of
    '+':result:=znak;
    '-':result:=znak;
    '(':result:=sko;
    ')':result:=skz;
    else
     result:=err;
   end;
   i:=i+1;
end;
end;
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 3)
сообщение
Сообщение #2


code warrior
****

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

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


Честно говоря, у тебя написано не очень правильно....
Попробуй вот этот вариант:
function Test(const S: string): boolean;
var Cur: integer; // индекс следующего символа
Len: integer; // длина строки входной
Look: char; // текущий символ

// вернёт истину, если достигнут конец строки
function LineEnd: boolean;
begin
Result:=Cur > Len;
end;

// вернёт истину, если символ удалось считать
function GetChar: boolean;
begin
if Cur <= Len then begin
Look:=S[Cur];
inc(Cur);
Result:=true
end else begin
Look:=#0;
Result:=false
end
end;

// проверяет, является ли символ + - или *
function IsOperator(C: Char): boolean;
begin
Result:=C in ['+','*','-']
end;

// является ли символ буквой (латиница)
function IsAlpha(C: char): boolean;
begin
Result:=UpCase( С ) in ['A'..'Z']
end;

// является ли цифрой (арабской smile.gif
function IsDigit(C: char): boolean;
begin
Result:=C in ['0'..'9']
end;

// <идентификатор>
function IsIdentifer: boolean;
begin
if IsAlpha(Look) then begin // <индетификатор>::=<буква>
while GetChar do //<индетификатор>::=<буква><цифра>
if not (IsAlpha(Look) or IsDigit(Look)) then Break;
Result:=true
end else Result:=false
end;

// <формула>
function IsFormula: boolean;
begin
if IsIdentifer then begin // <формула>::=<идентификатор>
Result:=true
end else if Look = '(' then begin // <формула>:=(<формула><знак><формула>)
GetChar; // пропускаем '('
if IsFormula then
if IsOperator(Look) then begin
GetChar; //пропускаем знак
if IsFormula then
if Look = ')' then begin
GetChar; // пропускаем ')'
Result:=true;
Exit;
end;
end;
Result:=false;
end else Result:=false;
end;

// инициализирует переменные и закачивает первый символ
procedure Init;
begin
Cur:=1;
Len:=Length(S);
GetChar;
end;

begin
Init;
// условие правильности: формула обнаружена и достигнут конец строки
Result:=IsFormula and LineEnd;
end;

распознаёт выражения типа:
Цитата
a
(aaa1+bbb1)
(x*(a+b))


--------------------
ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

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

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


Я вот тут написал свой вариант, он понимает вроде всё кроме выражения такого типа:4 или (4+6) , пишет что good, а должно быть bad, не могу правильно определить идентификатор. Подскажите плз, что и на что надо исправить в программе.

Код

procedure TForm1.Button1Click(Sender: TObject);
type
spisok=(ind, cif, znak, sko, skz);
var
res:spisok;
str:string;
i:byte;

function chit(var str:string; var i:byte):spisok;
begin
i:=i+1;
  if str[i] in ['A'..'z'] then result:=ind;
  if str[i] in ['0'..'9'] then result:=cif;
  case str[i] of
  '+':result:=znak;
  '-':result:=znak;
  '*':result:=znak;
  '(':result:=sko;
  ')':result:=skz
  else
     edit2.text:='bad';
  end;
end;

// вероятно косяк здесь
procedure indetif(var str:string; var i:byte);
begin
if str[i+1] in ['0'..'9'] then i:=i+1
end;

procedure proverka(var str:string; var i:byte; var res:spisok);
begin
res:=chit(str,i);
if res=ind then
  if i<>length(str) then indetif(str,i)
  else exit;
if res=sko then
  begin
  proverka(str,i,res);
  res:=chit(str,i);
  if res=znak then
   begin
   proverka(str,i,res);
   res:=chit(str,i);
   if res=skz then exit
    else edit2.Text:='bad';
   end
   else edit2.Text:='bad';
  end
else edit2.Text:='bad';
end;

begin
str:=edit1.text;
i:=0;
proverka(str,i,res);
if i=length(str) then edit2.Text:='good';
end;
end.  


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


code warrior
****

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

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


в коде разобраться - нереально :-))
погоняй лучше мой вариант


--------------------
ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 





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