打印字母列表中最长的子字符串

时间:2017-11-02 07:21:30

标签: sql oracle plsql oracle11g

任务要求按字母顺序打印最长的子字符串。例如:

'kotafgovlav' - >最长的字母子字符串:'afgov'

或者如果它们都相等,则应采取第一个:

'abcbcd' - >最长的字母子字符串:'abc'

这是我到目前为止所做的:

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;

正如你所看到的,我没有得到我想要的结果(甚至没有得到结果)。你可以给我一个提示/建议来解决这个任务吗?提前致谢。

4 个答案:

答案 0 :(得分:2)

您可以在单个SQL语句中执行此操作:

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

答案 1 :(得分:2)

您可以使用此块。

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;

答案 2 :(得分:1)

对于您的代码的第一个问题,使用exit退出循环可能是一个解决方案;

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;

......然后是所有算法。首先,你必须学习PL / SQL。

答案 3 :(得分:1)

只是为了让您了解使用过的dbms_output进行验证。以下是代码:

   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;