2013-11-12 8 views
0

Я пытаюсь запустить рекурсивную процедуру, которая переставляет заданную строку. Это компиляции на SQLDeveloper, но когда я пытаюсь запустить с вводом его дает мне ORA-06502: числовое или значение ошибки в строке 13 (назначение префикса)алгоритм рекурсивной перестановки в plsql

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; 
+0

Что вы используете в качестве входных значений? –

+0

Алгоритм неправильный. Вы добавляете символы в префикс, пока он не превысит 30 в одном из рекурсивных вызовов, и вы получите свою ошибку. Как должен работать алгоритм? У вас есть описание? –

+0

@BobJarvis print_anagrams ('', 'cat'); – user1203349

ответ

4

Существовали две проблемы:

Во-первых, функция возвращает LENGTHNULL, если его параметр NULL, а не 0, поэтому следующее условие в коде никогда не было правдой (поскольку strlen является NULL):

if strlen = 0 then 

Вы получали ошибку ora-06502: numeric or value errors, потому что, когда str аргумента был пуст, верхний предел диапазона FOR LOOP был NULL (потому что strlen является NULL):

for i in 1..NULL loop 

И это дает:

ora-06502: numeric or value errors 

Во-вторых, последний параметр функции substr в Oracle имеет другое значение, чем метод Stringsubstring в Java. В Oracle этот параметр означает «сколько символов должно быть возвращено», тогда как в Java это означает «конечный индекс подстроки, подлежащей возврату из исходной строки», поэтому следует изменить следующую строку:

stringg := SUBSTR(str,1,i) || SUBSTR(str,i+1,strlen); 

к:

stringg := SUBSTR(str,1,i - 1) || SUBSTR(str,i+1,strlen); 

изменение должно быть сделано, потому что в коде 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; 
/

Тест:

EXEC print_anagrams('', 'cat'); 

Выход:

cat 
cta 
act 
atc 
tca 
tac

Oracle Substr Function

Java String's substring method

Смежные вопросы