PL/SQL 创建回文测试器函数

PL/SQL creating a palindrome tester function

我在sqldeveloper.exe工作,我想

归档一个有效的回文测试器函数。

但是,由于一些非常不明显的原因,

word VARCHAR2(255) 或函数标识符对齐

用红色油漆。请有人指导我

走上这条绝路?提前致谢!

编辑:目前,我只服用

偶数基数的回文成

帐号。

我写的定义:

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;


你:

  • 函数签名中不需要大小;
  • RERURN而不是RETURN
  • 你的变量没有类型。
  • PALINNDROME 在函数末尾拼写错误。

你可以这样修复:

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;
/

注意:当单词的长度为奇数时,您不需要特殊情况,因为中间字母始终等于其自身。

但您可以将其简化为:

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

同时适用于偶数和奇数长度且无需区分的备选方案(对两种情况都适用):

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;
/

这实现了明显的递归:如果字符串为空或长度为 1,则它是回文。如果长度为 2 或更多,我们比较第一个和最后一个字符。如果它们不同,则该字符串不是回文。如果相同,则将它们都从字符串中删除,并检查剩余的子字符串是否为回文。

递归很昂贵;通过适当的优化级别,PL/SQL 优化器使用 for 循环重写函数,所以我们不需要担心这一点。

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