在PL / SQL中打印字母金字塔

时间:2017-10-13 11:30:12

标签: sql oracle plsql

我有一个练习写一个程序,打印出这样的字母金字塔:

    A
   ABA
  ABCBA
 ABCDCBA
ABCDFDCBA

该任务还建议使用INSTR,LPAD,UPPER。

我希望金字塔包含字母表中的所有字母。但是,我发现首先使用数字更容易:

IF x in 0..25 loop
dbms_output.put_line(x);
end loop;
end; 

结果只是从0到25的直线数字。我不知道如何在数字之前添加空格,最终需要字母,以形成金字塔形状。 请不要给出完整的答案,我只需要一些建议和指示来解决这个问题。

5 个答案:

答案 0 :(得分:4)

这个有效:

DECLARE
    aLine VARCHAR2(100);
BEGIN
    FOR PyramidLevel IN 0..25 LOOP
        aLine := NULL;

        FOR i IN 0..PyramidLevel-1 LOOP
            aLine := aLine || CHR(i+65);
        END LOOP; 

        FOR i IN REVERSE 0..PyramidLevel LOOP
            aLine := aLine || CHR(i+65);
        END LOOP;
        aLine := LPAD(aLine, 26+PyramidLevel);       

       DBMS_OUTPUT.PUT_LINE('_'||aLine);
    END LOOP;
END;


_                         A
_                        ABA
_                       ABCBA
_                      ABCDCBA
_                     ABCDEDCBA
_                    ABCDEFEDCBA
_                   ABCDEFGFEDCBA
_                  ABCDEFGHGFEDCBA
_                 ABCDEFGHIHGFEDCBA
_                ABCDEFGHIJIHGFEDCBA
_               ABCDEFGHIJKJIHGFEDCBA
_              ABCDEFGHIJKLKJIHGFEDCBA
_             ABCDEFGHIJKLMLKJIHGFEDCBA
_            ABCDEFGHIJKLMNMLKJIHGFEDCBA
_           ABCDEFGHIJKLMNONMLKJIHGFEDCBA
_          ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
_         ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
_        ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
_       ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
_      ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
_     ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
_    ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
_   ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
_  ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
_ ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
_ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA

看起来DBMS_OUTPUT.PUT_LINE()修剪前导空格字符(至少在我的TOAD中),所以我将_放在开头。

答案 1 :(得分:4)

使用模型子句的纯SQL

select lpad(x1, 26, ' ') || substr(x2, 2) x from dual
model
dimension by (1 id)
measures (cast(null as varchar2(26)) x1, cast(null as varchar2(26)) x2)
(x1[for id from 1 to 26 increment 1] = x1[cv(id)-1] || chr(64+cv(id)),
x2[for id from 1 to 26 increment 1] = chr(64+cv(id)) || x2[cv(id)-1]);

X
---------------------------------------------------
                         A
                        ABA
                       ABCBA
                      ABCDCBA
                     ABCDEDCBA
                    ABCDEFEDCBA
                   ABCDEFGFEDCBA
                  ABCDEFGHGFEDCBA
                 ABCDEFGHIHGFEDCBA
                ABCDEFGHIJIHGFEDCBA
               ABCDEFGHIJKJIHGFEDCBA
              ABCDEFGHIJKLKJIHGFEDCBA
             ABCDEFGHIJKLMLKJIHGFEDCBA
            ABCDEFGHIJKLMNMLKJIHGFEDCBA
           ABCDEFGHIJKLMNONMLKJIHGFEDCBA
          ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
         ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
        ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
       ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
      ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
     ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
    ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
   ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
  ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
 ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA

26 rows selected.

更新。只是为了好玩,单一规则的结果相同

select lpad(' ', 26 - ceil(length(x)/2), ' ')  || x as x from dual
model
dimension by (1 id)
measures (cast(null as varchar2(51)) x)
(x[for id from 1 to 26 increment 1] = substr(x[cv(id)-1], 1, cv(id)-1) || chr(64+cv(id)) || substr(x[cv(id)-1], cv(id)-1));

select lpad(' ', 26 - ceil(length(x)/2), ' ')  || x as x
from (select 'A' x from dual union all select 'ABA' from dual)
model
dimension by (rownum id)
measures (cast(x as varchar2(51)) x)
(x[for id from 3 to 26 increment 1] = regexp_replace(x[cv(id)-1], '(.)(.)\1', '\1\2' || chr(64+cv(id)) || '\2\1'));

答案 2 :(得分:3)

这样做的一种方法是生成金字塔的基础:

  • CHR(n)将生成ASCII字符;和
  • 您可以使用||连接字符串,以便str := str || CHR(65)A附加到字符串的末尾。
  • FOR i IN [REVERSE] 1 .. repetitions LOOP语句可用于循环遍历值。

如果你可以生成基础,那么TRANSLATE function可以用一对一的对应关系替换多个字符和其他字符,所以:

  • TRANSLATE( 'ABC', 'ABC', ' A' )输出' A'
  • TRANSLATE( 'ABC', 'ABC', ' AB' )输出' AB'
  • TRANSLATE( 'ABC', 'ABC', 'ABC' )输出'ABC'

如果你已经生成了金字塔的底部,那么你有一个字符串,其中子字符串以这些字符开头,你只需要用空格填充的适当长度的子字符串。

DBMS_OUTPUT.PUT_LINE( string )会将一个字符串打印到控制台。

Full Solution - DO NOT FOLLOW THE LINK IF YOU DON'T WANT TO KNOW HOW I DID THIS

答案 3 :(得分:1)

两个建议:

在第一行有1个字母,在第二行有3个字母,在第三行有5个字母......所以1,3,5,7,9 ....到无限。我不明白你想要什么:

IF x in 0..25 loop

dbms_output的换行符是:

chr(13)||chr(10) -> Windows
chr(10) -> Unix

答案 4 :(得分:1)

您可以在SQL中完成所有操作。这适用于Toad(作为脚本运行; F5)。注意我得到了一个"无效的号码"错误,除非我包裹了" level-1"在第二次regexp_substr调用中的TO_NUMBER()调用中。

提示:使用CONNECT BY构造循环遍历行。 CONNECT BY自动生成一个名为level的变量,该变量在每次迭代时递增。

寻找模式。预计有多少行?每行第一个字母前面有多少个空格?您可以在计算中操作哪些变量?其他答案也提供了提示。

您是否注意到Fibonacci序列?每行上的字符数是该行数加上前一行的数量之和(与答案无关(至少我的答案),只是我注意到的一种模式)。

SQL fiddle example answer here, but leading spaces will not show. You have to paste the solution into Toad or SQLPlus and uncomment the "set" lines.

编辑:我去了SQL Fiddle试了一下,发现它已经挂了。因为我不想让我的答案丢失,而且每个人都在发布完整的答案,这是为了后人:

SQL> set heading off;
SQL> set feedback off;
SQL> set pagesize 0;
SQL>
SQL> select lpad(' ', 26-level, ' ') ||
     regexp_substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', '(.{' || level ||'})', 1, 1, NULL, 1) ||
     reverse(regexp_substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', '(.{' || to_number(level-1) ||'})', 1, 1, NULL, 1)) pyramid
     from dual
     connect by level <= 26;

                         A
                        ABA
                       ABCBA
                      ABCDCBA
                     ABCDEDCBA
                    ABCDEFEDCBA
                   ABCDEFGFEDCBA
                  ABCDEFGHGFEDCBA
                 ABCDEFGHIHGFEDCBA
                ABCDEFGHIJIHGFEDCBA
               ABCDEFGHIJKJIHGFEDCBA
              ABCDEFGHIJKLKJIHGFEDCBA
             ABCDEFGHIJKLMLKJIHGFEDCBA
            ABCDEFGHIJKLMNMLKJIHGFEDCBA
           ABCDEFGHIJKLMNONMLKJIHGFEDCBA
          ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
         ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
        ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
       ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
      ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
     ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
    ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
   ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
  ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
 ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA
SQL>