Reputation: 37
The task asks to print the longest substring in the alphabetical order. For example:
'kotafgovlav' -> longest alphabetical substring: 'afgov'
or if they are both equal long then the first one should be taken:
'abcbcd' -> longest alphabetical substring: 'abc'
Here is the what I've done so far:
DECLARE
x varchar2(12) := 'kotafgovlav';
ind varchar2(12);
BEGIN
for i in 1..length(x) loop
if substr(x, i, 1) > substr(x, i-1, 1)
end if;
end loop;
END;
As you can see, I didn't get the result that i wanted (not even close). Can you maybe give me a hint/suggestions to solve this task? Thanks in advance.
Upvotes: 0
Views: 84
Reputation: 31666
You can use this block.
SET SERVEROUTPUT ON;
DECLARE
x VARCHAR2(12) := 'kotafgovlav';
l_substr VARCHAR2(12) := SUBSTR(x,1,1);
l_longest VARCHAR2(12) := SUBSTR(x,1,1);
BEGIN
FOR i IN 2..length(x)
LOOP
IF ASCII( SUBSTR(x,i,1) ) >= ASCII( SUBSTR(x,i-1,1) ) THEN
l_substr := l_substr||SUBSTR(x,i,1);
ELSE
IF LENGTH(l_substr) >= LENGTH(l_longest) THEN
l_longest := l_substr;
END IF;
l_substr := SUBSTR(x,i,1);
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('longest substring '||l_longest);
END;
Upvotes: 2
Reputation: 346
Just to make you understand used dbms_output to verify. Below is the code :
DECLARE
x varchar2(12) := 'pqrsabc1de';
ind varchar2(12);
counter number := 1;
max_counter number := 0;
str_cr varchar2(100);
str varchar2(100);
BEGIN
str_cr := str_cr || substr(x, 1, 1);
for i in 1..length(x) loop
-- dbms_output.put_line('one:'||substr(x, i, 1));
-- dbms_output.put_line('two:'||substr(x, i+1, 1));
if substr(x, i+1, 1) > substr(x, i, 1) then
counter := counter + 1;
str_cr := str_cr || substr(x, i+1, 1);
-- dbms_output.put_line('str_cr:'||str_cr);
-- dbms_output.put_line('counter:'||counter);
else
if max_counter < counter then
max_counter := counter;
str := str_cr;
str_cr := substr(x, i+1, 1);
counter := 1;
else
str_cr := substr(x, i+1, 1);
counter := 1;
end if;
-- dbms_output.put_line('str:'||str);
-- exit; -- exits current loop
end if;
end loop;
dbms_output.put_line('str_final:'||str);
END;
Upvotes: 1
Reputation: 168051
You can do it in a single SQL statement:
SELECT substring
FROM (
SELECT RANK() OVER ( ORDER BY LEVEL DESC ) As rnk,
SUBSTR(
str,
CONNECT_BY_ROOT( idx ),
idx - CONNECT_BY_ROOT( idx ) + 1
) AS substring
FROM (
SELECT LEVEL AS idx,
str,
SUBSTR( str, LEVEL, 1 ) As value
FROM ( SELECT 'kotafgovlav' AS str FROM DUAL )
CONNECT BY LEVEL <= LENGTH( str )
)
WHERE CONNECT_BY_ISLEAF = 1
CONNECT BY PRIOR value < value
AND PRIOR idx + 1 = idx
)
WHERE rnk = 1
Upvotes: 2
Reputation: 8395
For the first issue with your code, getting out of your loop with exit
could be a solution;
DECLARE
x varchar2(12) := 'kotafgovlav';
ind varchar2(12);
BEGIN
for i in 1..length(x) loop
if substr(x, i, 1) > substr(x, i-1, 1) then
dbms_output.put_line('i:'||i);
-- here do something because your test is ok
exit; -- exits current loop
end if;
end loop;
END;
... Then it's all algorithm. First you must learn PL/SQL.
Upvotes: 1