首先打印非重复字符

时间:2017-03-12 11:15:27

标签: oracle plsql

我是PL / SQL的新手,我正在尝试编写一个程序,首先打印输入字符串的非重复字符,然后重复字符串中的字符。例如,如果输入字符串是“Array”,则输出应为“yArra”。

我写了一部分用于搜索否。重复字符的出现,但不知道它应该在第一时间打印出来。

我写了一个关于如何使其工作但却难以编码的算法

提前感谢您的帮助!

5 个答案:

答案 0 :(得分:1)

尝试并使用REGEXP_COUNT函数。您可以先提供一个过滤器,其结果为> 1以查找重复的字符,然后将它们与count = 1的那些连接起来。

Check how to use regexp_count

答案 1 :(得分:1)

  

我正在尝试编写一个可以打印非重复的过程   首先输入字符串的字符和重复的字符   最后一个字符串。

您可以使用纯PLSQL代码执行此操作,如下所示:

create or replace procedure prnt_letter(strng varchar2) as

  var  varchar2(1);
  var1 varchar2(1000) := '';
  var2 varchar2(1);
  var3 varchar2(1000) := '';

  strn_len number;

begin

  dbms_output.put_line('Input String --> ' || strng);

  strn_len := length(strng);

  var := substr(strng, 1, 1);

  for i in 1 .. strn_len loop

    if (var = substr(strng, i, 1)) then
      var2 := substr(strng, i, 1);
      var3 := var3 || var2;
      var  := substr(strng, i, 1);
    else
      var1 := var1 || substr(strng, i, 1);
      var  := substr(strng, i, 1);
    end if;

  end loop;
  dbms_output.put_line('Output String --> '||var1 || var3);

end;

修改 以下是我在PLSQLSQL中修订的解决方案。这适用于任何字符串。

PLSQL:

create or replace procedure prnt_letter(strng varchar2) as

  var1 varchar2(1000) := '';
  strn_len number;

begin

  dbms_output.put_line('Input String --> ' || strng);

  strn_len := length(strng);

   SELECT reverse (LISTAGG (vertical, '') WITHIN GROUP (ORDER BY 1 DESC)) 
   into var1
    FROM (    
            SELECT SUBSTR (strng, LEVEL, 1) Vertical
            FROM DUAL
            CONNECT BY LEVEL <= strn_len            
         ) ;

  dbms_output.put_line('Output String --> '||var1 );

end;

输出:

SQL> execute prnt_letter('rajjjjkkmmaaljjjl');
Input String --> rajjjjkkmmaaljjjl
Output String --> rmmllkkjjjjjjjaaa

PL/SQL procedure successfully completed.

SQL> execute prnt_letter('bubble');
Input String --> bubble
Output String --> ulebbb

PL/SQL procedure successfully completed.

SQL: - 使用的逻辑:

  • 1)输入字符串首先垂直排列在不同的行中 然后命令

  • 2)使用LISTAGG,结果汇总为单个有序字符串

  • 3)使用REVERSE将非重复字符串带到起始位置 字符串。

    SELECT reverse (LISTAGG (vertical, '') WITHIN GROUP (ORDER BY 1 DESC)) col1 FROM ( SELECT SUBSTR ('rajjjjkkmmaaljjjl', LEVEL, 1) Vertical FROM DUAL CONNECT BY LEVEL <= LENGTH ('rajjjjkkmmaaljjjl')
    )

答案 2 :(得分:1)

我认为只需使用纯SQL而不是使用PLSQL就可以实现解决方案。希望在片段下方有所帮助。

SELECT a.COL
  ||REPLACE('&Enter_text',a.col,'') output
FROM
  (SELECT regexp_count('&Enter_text',SUBSTR('&Enter_text',level,1)) col1,
    SUBSTR('&Enter_text',level,1) col
  FROM DUAL
    CONNECT BY level <=LENGTH('&Enter_text')
  )a
WHERE a.col1 = 1;

答案 3 :(得分:1)

这很有趣,所以我使用关联数组作为Hashmap,可以轻松理解。对于非案例敏感性,还有一些微妙的东西:

CREATE OR REPLACE FUNCTION f(p_str in varchar2)
  RETURN varchar2
AS
  TYPE map_v IS TABLE OF integer INDEX BY varchar2(1);
  l_dup map_v;
  i PLS_INTEGER;
  l_c varchar2(1);
  l_tc varchar2(1);
  l_nb_occurrences integer := NULL;
  l_out_sngl varchar2(2000) := '';
  l_out_dupl varchar2(2000) := '';
BEGIN
--  l_dup('a'):=0;
--  l_dup('b'):=0;

-- first loop to count occurrences
  i:=1;
  LOOP
    l_c := lower(substr(p_str, i, 1));   
    begin
      l_nb_occurrences := l_dup(l_c);
      l_dup(l_c) := l_nb_occurrences + 1;
      dbms_output.put_line(l_c||':incr:'||i);

    exception 
      when no_data_found then
        l_dup(l_c) := 1;
        dbms_output.put_line(l_c||':pushed:'||i);        
      when others then 
        raise;
    end;
    i := i+1;
  EXIT WHEN i > length(p_str);
  END LOOP;

  -- second loop for building output
  i:=1;
  LOOP
    l_c := lower(substr(p_str, i, 1));   
    l_tc := substr(p_str, i, 1);
    begin
      l_nb_occurrences := l_dup(l_c);
        dbms_output.put_line(l_c||':xx:'||i||'||'||l_nb_occurrences);        
      if l_nb_occurrences = 1 then
        l_out_sngl := l_out_sngl || l_tc;
      else 
        l_out_dupl := l_out_dupl || l_tc;
      end if;

    exception 
      when no_data_found then
        dbms_output.put_line('why? there should be (see first loop).');        
      when others then 
        raise;
    end;
    i := i+1;
  EXIT WHEN i > length(p_str);
  END LOOP;

  return l_out_sngl || l_out_dupl;
exception
  when others then
    dbms_output.put_line(sqlerrm);
END f;
/

结果如下:

select f('Array') from dual;
-- yArra
select f('Bubbles') from dual;
-- ulesBbb

答案 4 :(得分:-2)

试试这个功能......

CREATE OR REPLACE FUNCTION non_repeating_char_first (v_input IN varchar2)
   RETURN varchar2
IS
   str1 varchar2 (100);
   str2 varchar2 (100);   
   v_match    number;
   v_output   varchar2 (100);
BEGIN
   str1 := '';
   str2 := '';

   FOR i IN 1 .. LENGTH (v_input)
   LOOP

         SELECT   REGEXP_COUNT (v_input,
                                SUBSTR (v_input, i, 1),
                                1,
                                'i')
           INTO   v_match
           FROM   DUAL;

         IF v_match =1 THEN
           str1 :=str1||SUBSTR (v_input, i, 1);
         else
           str2 :=str2||SUBSTR (v_input, i, 1);             
         END IF;
   END LOOP;
   v_output:=str1||str2;
   RETURN v_output;
END;