I am working in sqldeveloper.exe and I would like to
archive a working palindrome tester function.
However, for some pretty non-obvious reason the
word VARCHAR2(255) or the function identifier is aligned
with red paint. Could please someone guide me
on this road of desperation? Thank you in advance!
EDIT: For now, I am only taking
palindromes with even cardinality into
account.
The definition I wrote:
CREATE OR REPLACE FUNCTION PALINDROME(WORD VARCHAR2(255)) RETURN
INT IS
N := LENGTH(WORD) / 2;
I := 1;
J := LENGTH(WORD);
BEGIN
WHILE I <= N AND SUBSTR(WORD, I, 1) = SUBSTR(WORD, J, 1) LOOP
I := I 1;
J := J - 1;
END LOOP;
IF I = N 1 THEN
RETURN 1;
ELSE
RERURN 0;
END IF;
END PALINNDROME;
CodePudding user response:
You:
- do not need a size in the function's signature;
- have
RERURN
instead ofRETURN
- Do not have types on your variables.
PALINNDROME
is misspelt at the end of the function.
You can fix it like this:
CREATE OR REPLACE FUNCTION PALINDROME(
WORD VARCHAR2
) RETURN INT
IS
N PLS_INTEGER := LENGTH(WORD) / 2;
I PLS_INTEGER := 1;
J PLS_INTEGER := LENGTH(WORD);
BEGIN
WHILE I <= N AND SUBSTR(WORD, I, 1) = SUBSTR(WORD, J, 1) LOOP
I := I 1;
J := J - 1;
END LOOP;
IF I = N 1 THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END PALINDROME;
/
Note: You do not need a special case when the word has an odd length as the middle letter is always equal to itself.
But you can simplify it to:
CREATE OR REPLACE FUNCTION PALINDROME(
WORD VARCHAR2
) RETURN INT
IS
BEGIN
FOR I IN 1 .. LENGTH(word)/2 LOOP
IF SUBSTR(WORD, I, 1) <> SUBSTR(WORD, -I, 1) THEN
RETURN 0;
END IF;
END LOOP;
RETURN 1;
END PALINDROME;
/
db<>fiddle here
CodePudding user response:
An alternative that works for both even and odd length, and doesn't need to distinguish (it works the same for both cases):
create or replace function palindrome_check(str varchar2) return number as
begin
return case when length(str) > 1
then case when substr(str, 1, 1) != substr(str, -1, 1) then 0
else palindrome_check(substr(str, 2, length(str) - 2))
end
else 1
end;
end;
/
This implements the obvious recursion: if the string is empty or has length 1 then it is a palindrome. If the length is 2 or more, we compare the first and the last character. If they are different then the string is not a palindrome. If they are the same, remove them both from the string and check if the remaining substring is a palindrome.
Recursion is expensive; with the proper optimization level, the PL/SQL optimizer rewrites the function using a for
loop, so we don't need to be concerned about that.
with
test_strings (str) as (
select null from dual union all
select 'x' from dual union all
select 'zz' from dual union all
select 'ab' from dual union all
select 'lol' from dual union all
select 'lot' from dual union all
select 'abba' from dual union all
select 'mmmm' from dual union all
select 'mama' from dual union all
select 'radar' from dual union all
select 'poker' from dual union all
select 'pullup' from dual
)
select str, palindrome_check(str) as is_palindrome from test_strings;
STR IS_PALINDROME
------ -------------
1
x 1
zz 1
ab 0
lol 1
lot 0
abba 1
mmmm 1
mama 0
radar 1
poker 0
pullup 1