Rekurencyjna funkcja do sprawdzania, czy słowo jest palindromem

0

Taki oto kod:

function czyPalindrom(slowo : string; i, j : byte) : boolean;
BEGIN
    if i < j then
       if slowo[i] = slowo[j] then
          czyPalindrom(slowo, i+1, j-1)
       else
          czyPalindrom := FALSE
    else
          czyPalindrom := TRUE;
END; 
{wywołanie w głównym bloku:}
 writeln('Wynik palindromu: ', czyPalindrom('kajak', 1, 5)); 

Wyniki:
dla kajak : TRUE
dla KajaK : TRUE
dla aca: TRUE
Niestety program się wysypuje:
dla kajakk : TRUE [a to nie jest palindrom przecież.., wywołanie czyPalindrom('kajak', 1, 6) ]
dla acaa: TRUE [a to nie jest palindrom przecież.., wywołanie czyPalindrom('acaa', 1, 4) ]
Gdzie leży błąd ? :/

0

if'y dzielą twój kod na trzy części, w dwóch częściach wiadomo co zwróci funkcja, zaś w trzeciej - nie wiadomo.

0

dzięki za odpowiedź, jednakże prosiłbym o pokazanie / wytłumaczenie w jaki sposób nie sprawdzam 3ciej części i propos czemu akurat na 3 części ify dzieli mi ten program ?

Tok rozumowania:
Pierwszy IF:
i < j
else (przypadek, gdy i>=j)
Drugi IF:
slowo[i] = slowo[j];
else (slowo[i] <> slowo[j])
Nie widze innych przypadków

0
function czyPalindrom(slowo : string; i, j : byte) : boolean;
BEGIN
    if i < j then
       if slowo[i] = slowo[j] then
       begin
          czyPalindrom(slowo, i+1, j-1);
          czyPalindrom := W_TYM_PRZYPADKU_ZWRÓĆ_WARTOŚĆ_LOSOWĄ;
       end
       else
          czyPalindrom := FALSE
    else
          czyPalindrom := TRUE;
END;
0

Jeśli już koniecznie miałbym się bawić stosem, to w nieco inny sposób:

function IsPalindrome(const AWord: AnsiString; const ALeftIdx, ARightIdx: Byte): Boolean;
begin
  if ALeftIdx < ARightIdx then
  begin
    Result := AWord[ALeftIdx] = AWord[ARightIdx];

    if Result then
      Result := IsPalindrome(AWord, ALeftIdx + 1, ARightIdx - 1);
  end
  else
    Result := True;
end;

A jak już koniecznie chcesz na kształt oldschoolowego Pascala i swoich warunków, to tak jak poniżej:

function IsPalindrome(const AWord: AnsiString; const ALeftIdx, ARightIdx: Byte): Boolean;
begin
  if ALeftIdx < ARightIdx then
  begin
    if AWord[ALeftIdx] = AWord[ARightIdx] then
      IsPalindrome := IsPalindrome(AWord, ALeftIdx + 1, ARightIdx - 1)
    else
      IsPalindrome := False;
  end
  else
    IsPalindrome := True;
end;

Jak widać, po spełnieniu dwóch warunków wynik kolejnego, rekurencyjnego wywołania jest wpisywany do rezultatu obecnej instancji funkcji, czego u Ciebie nie było, stąd wynik rekurencyjnych wywołań był zwracany w próżnię.

1

Czemu nie dać po ludzku:

function IsPalindrome(const AWord:AnsiString;Lf,Rt:Integer):Boolean;
begin
  Result:=(Lf>=Rt)or(AWord[Lf]=AWord[Rt])and(IsPalindrome(AWord,Lf+1,Rt-1));
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1