Plsql 将十进制转换为三个堆栈
我正在尝试使用下一个逻辑或类似的东西将十进制数转换为,呃,三个堆栈,但我无法获得严格的alogrythm:Plsql 将十进制转换为三个堆栈,plsql,scripting,Plsql,Scripting,我正在尝试使用下一个逻辑或类似的东西将十进制数转换为,呃,三个堆栈,但我无法获得严格的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
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;
谢谢。这里有一种方法是一致的和向后兼容的,而且它可以在一个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
ETA:这里有一种方法,可以将ids=1到7的模式的结果简单地添加到第n-1个模式中,例如,对于id=8,模式与id=1 col1=col2=col3-1相同,但在每列中加上1,id=15是相同的模式,这是第三次:
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\u col中返回正确答案;您不一定需要外部查询
注意,我假设你只想要正整数;我不想说负整数会发生什么。将数字分成三部分的逻辑是什么?它一开始看起来非常像二进制,但后来我们找到了8,变成了0,0,2。为什么不是1,1,2?这三列代表什么?8看起来很糟糕,因为我没有第四列和第四列,所以我需要分成三部分。事实上,8可以是1,1,2,但它会打破顺序。好的,但是为什么它是0,0,2的逻辑是什么?我们是不是应该能够获取这三列并从中重构相应的十进制值?@Boneist,是的,我希望能够双向转换。0,0,2作为下一个序列值对我来说很自然。比如使用下一个秩。那么为什么1=0,0,1而2=0,1,0和8=0,0,2呢?如果列以二进制形式表示2^2、2^1、2^0,那么8将是0、0、8或1、1、2。你为什么要把这些值分成三列呢?这背后的目的是什么?我已经更新了我的答案,加入了一个方法,可以更均匀地在列之间共享值。谢谢,这绝对是我所期望的。感谢你的帮助和时间。
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