plsql中的递归排列算法

use*_*349 1 sql oracle recursion plsql oracle-sqldeveloper

我正在尝试运行一个置换给定字符串的递归过程.它正在sqldeveloper上进行编译但是当我尝试使用输入运行时它给我ora-06502:第13行的数字或值错误(前缀赋值)

create or replace 
  procedure print_anagrams
  (pre in varchar2, str in varchar2)
  is
    prefix varchar2(30);
    stringg varchar2(30);
    strlen number;
  begin
    strlen := length(str);
    if strlen = 0 then
     dbms_output.put_line(pre);
    else
      for i in 1..strlen loop
        prefix := pre || SUBSTR(str,i,1);
        stringg := SUBSTR(str,1,i) || SUBSTR(str,i+1,strlen);
        print_anagrams(prefix,stringg);
      end loop;
    end if;
  end;
Run Code Online (Sandbox Code Playgroud)

Prz*_*lej 5

有两个问题:

首先,LENGTH函数返回NULL如果它的参数NULL,而不是0,那么在你的代码下面的条件为永真(因为strlenNULL):

if strlen = 0 then
Run Code Online (Sandbox Code Playgroud)

你得到ora-06502: numeric or value errors的错误,因为,当str自变量是空的,的范围的上限FOR LOOPNULL(因为strlenNULL):

for i in 1..NULL loop
Run Code Online (Sandbox Code Playgroud)

这会产生:

ora-06502: numeric or value errors
Run Code Online (Sandbox Code Playgroud)

其次,substrOracle中函数的最后一个参数与Java中Stringsubstring方法有不同的含义.在Oracle中,该参数表示"应返回多少个字符",而在Java中,它表示"从原始字符串返回的子字符串的结束索引",因此应更改以下行:

stringg := SUBSTR(str,1,i) || SUBSTR(str,i+1,strlen);
Run Code Online (Sandbox Code Playgroud)

至:

stringg := SUBSTR(str,1,i - 1) || SUBSTR(str,i+1,strlen);
Run Code Online (Sandbox Code Playgroud)

必须进行更改,因为在您提供链接的Java代码中,循环从0开始,并且0作为第三个参数传递,这导致在循环的第一次迭代时返回空字符串.如果没有更改,PL/SQL版本中的第一次迭代将返回参数中的第一个字符.

最后,你得到一个工作程序:

create or replace 
  procedure print_anagrams
  (pre in varchar2, str in varchar2)
  is
    prefix varchar2(30);
    stringg varchar2(30);
    strlen number;
  begin
    strlen := length(str);
    if NVL(strlen, 0) = 0 then
     dbms_output.put_line(pre);
    else
      for i in 1..strlen loop
        prefix := pre || SUBSTR(str,i,1);
        stringg := SUBSTR(str,1,i - 1) || SUBSTR(str,i+1,strlen);
        print_anagrams(prefix,stringg);
      end loop;
    end if;
  end;
/
Run Code Online (Sandbox Code Playgroud)

测试:

EXEC print_anagrams('', 'cat');
Run Code Online (Sandbox Code Playgroud)

输出:

cat
cta
act
atc
tca
tac

Oracle Substr功能

Java String的子串方法