2017-01-17 4 views
0

Я пытаюсь преобразовать десятичное число, errmm, три штабеля с помощью следующей логики или что-то подобное, но я не могу получить строгий alogrythm:Преобразование десятичного трех стеков

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; 

Thankyou.

+1

Какова логика разделения числа на три части? Он начинает выглядеть очень много, как бинарный, но затем мы набираем 8, что идет (0,0,2). Почему это не (1,1,2)? Что представляют собой три столбца? – Boneist

+0

выглядит ужасно, потому что у меня нет четвертого и последующих рангов, поэтому мне нужно разделить три части. на самом деле это может быть (1,1,2) для 8, но он сломает последовательность. –

+0

Хорошо, но какова логика, почему это (0, 0, 2)? Подразумеваем ли мы, что у вас есть три столбца и выберем из них соответствующее десятичное значение? – Boneist

ответ

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: Вот способ, который принимает результаты для шаблона для DS = 1 до 7, и просто добавляет, что к (п-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 

(I» ve только поместил внешний запрос вокруг основного запроса, чтобы доказать, что значения столбца вернут правильный ответ в check_col; вам необязательно потребуется внешний запрос.)

N.B. Я предполагаю, что вы только хотите это для целых положительных чисел; Я не хотел бы говорить, что произойдет с отрицательными целыми числами.

+0

Я обновил свой ответ, чтобы включить метод, который «разделяет» значения по столбцам более равномерно. – Boneist

+0

Спасибо, это абсолютно то, чего я ожидал. Цените свою помощь и время. –