将十进制转换为三个堆栈

时间:2017-01-17 10:51:32

标签: plsql scripting

我正在尝试使用下一个逻辑或类似的东西将十进制数转换为,错误,三个堆栈,但我无法获得严格的算法:

1       0   0   1
2       0   1   0
3       0   1   1
4       1   0   0
5       1   0   1
6       1   1   0
7       1   1   1
8       0   0   2
9       0   2   0
10      0   2   1
11      2   0   0
12      1   0   2
13      1   1   2
14      1   2   1
15      2   0   1
16      2   1   0
17      2   1   1
18      2   1   2

第一个建议是使用两个内部循环,一个用于减少输入(十进制),第二个用于在堆栈之间切换。

在pl-sql中进行了半尝试(它正在向后工作):

declare
type arr_type is table of varchar(32) index by binary_integer;
arr arr_type;
i number := 12;
z number := 0;
x number := 0;
c number := 0;
gg number;
begin
  arr(1) := 'z';
  arr(2) := 'x';
  arr(3) := 'c';
  gg := 0; -- array position
  i  := i + 1;  -- 
    loop
    i  := i - 1;
    gg := gg + 1;
      if arr(gg) = 'z' 
        then 
          z := z + 1;
          --if c > 0 then c := c - 1; end if;
      elsif arr(gg) = 'x'
        then 
          x := x + 1;
          --if z > 0 then z := z - 1; end if;
      elsif arr(gg) = 'c'
        then 
          c := c + 1;
          --if x > 0 then x := x - 1; end if;
      end if;
      --
      if gg = 3 then gg := 0;
      end if;
    if i = 1 then exit; end if;
    dbms_output.put_line(z || ' ' || x || ' ' || c);
    end loop;
end;

三江源。

1 个答案:

答案 0 :(得分:0)

这是一种一致且向后兼容的方式,而且可以在单个SQL语句中完成:

WITH sample_data AS (SELECT LEVEL ID FROM dual CONNECT BY LEVEL <= 16)
SELECT id,
       FLOOR(ID/4) "2^2",
       4*FLOOR(ID/4),
       ID - 4*FLOOR(ID/4),
       floor((ID - 4*FLOOR(ID/4))/2) "2^1",

       ID - 2*(floor((ID - FLOOR(ID/4))/2)) "2^0"
FROM   sample_data;

WITH sample_data AS (SELECT LEVEL ID FROM dual CONNECT BY LEVEL <= 16)
-- end of generating sample data for the below query to work on
SELECT id,
       FLOOR(ID/4) "2^2",
       FLOOR( (ID - 4*FLOOR(ID/4)) /2) "2^1",
       ID - 4*FLOOR(ID/4) - 2*FLOOR( (ID - 4*FLOOR(ID/4)) /2) "2^0"
FROM   sample_data;

        ID        2^2        2^1        2^0
---------- ---------- ---------- ----------
         1          0          0          1
         2          0          1          0
         3          0          1          1
         4          1          0          0
         5          1          0          1
         6          1          1          0
         7          1          1          1
         8          2          0          0
         9          2          0          1
        10          2          1          0
        11          2          1          1
        12          3          0          0
        13          3          0          1
        14          3          1          0
        15          3          1          1
        16          4          0          0

并且只是为了证明它向后兼容(并且它适用于您将值扩展到3列):

WITH sample_data2 AS (SELECT 1 col1, 1 col2, 2 col3 FROM dual UNION ALL
                      SELECT 2 col1, 0 col2, 0 col3 FROM dual UNION ALL
                      SELECT 1 col1, 2 col2, 0 col3 FROM dual UNION ALL
                      SELECT 0 col1, 1 col2, 2 col3 FROM dual)
SELECT col1,
       col2,
       col3,
       col1*4 + col2*2 + col3 decimal_number
FROM   sample_data2;

      COL1       COL2       COL3 DECIMAL_NUMBER
---------- ---------- ---------- --------------
         1          1          2              8
         2          0          0              8
         1          2          0              8
         0          1          2              4

ETA:这里采用ids = 1到7的模式结果,并简单地将其添加到第(nth-1)个模式(例如,对于id = 8,模式与id = 1(col1 = col2 = col3 -1)但每列加1),id = 15是第3次相同的模式:

WITH sample_data AS (SELECT LEVEL -1 ID FROM dual CONNECT BY LEVEL <= 21)
SELECT ID,
       col1,
       col2,
       col3,
       col1 * 4 + col2 * 2 + col3 check_col
FROM   (SELECT ID,
               floor((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (1,2,3) THEN 0
                                 --     WHEN ID = 0 THEN 1
                                  ELSE 1
                             END col1,
               FLOOR((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (1,4,5) THEN 0
                                  --    WHEN ID = 0 THEN 1
                                  ELSE 1
                                 END col2,
               FLOOR((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (2,4,6) THEN 0
                          ELSE 1
                     END col3
        FROM   sample_data) "MAIN";

        ID       COL1       COL2       COL3  CHECK_COL
---------- ---------- ---------- ---------- ----------
         0          0          0          0          0
         1          0          0          1          1
         2          0          1          0          2
         3          0          1          1          3
         4          1          0          0          4
         5          1          0          1          5
         6          1          1          0          6
         7          1          1          1          7
         8          1          1          2          8
         9          1          2          1          9
        10          1          2          2         10
        11          2          1          1         11
        12          2          1          2         12
        13          2          2          1         13
        14          2          2          2         14
        15          2          2          3         15
        16          2          3          2         16
        17          2          3          3         17
        18          3          2          2         18
        19          3          2          3         19
        20          3          3          2         20

(我只是在主查询周围放置外部查询来证明列值在check_col中返回正确的答案;你不一定需要外部查询。)

N.B。我假设你只想要正整数;我不想说负面整数会发生什么。