Oracle实现约瑟夫环

CREATE  PROCEDURE   prc_joserph_ring
(p_sodilers   IN  integer,  
 p_shift  IN  integer, 
 p_msg  OUT   varchar2)
IS
    k integer:=0;  
    v_idx integer:=0;
    Type joserph IS TABLE OF integer INDEX BY BINARY_INTEGER;
     v_soilders joserph;
BEGIN
    FOR i in 1..p_sodilers LOOP   v_soilders(i):=i;   END LOOP;
    WHILE v_soilders.count>=1 LOOP
     	IF v_soilders.next(v_idx) is not null then       
 		v_idx :=v_soilders.next(v_idx );
     	else
 		v_idx :=v_soilders.first;       
     	end if;
     	k:=k+1;
     	if mod(k,p_shift )=0 then
       		p_msg  := p_msg || ',' ||  v_soilders(v_idx);
       		v_soilders.delete(v_idx);           
     	end if;
  END LOOP;
END;
declare 
  v_msg varchar2(100); 
begin
  -- Test statements here
  prc_joserph_ring(20,4,v_msg);--20个士兵
  DBMS_OUTPUT.put_line(v_msg);
end;

游标实现

CREATE TABLE soilders(--创建表
 ind int ,
 quit_order int );
DECLARE
     v_total integer := &total;
     v_step  integer := &n;
     CURSOR  cur_soilder  IS  
            SELECT * FROM  soilders WHERE quit_order=0 FOR UPDATE;  
     k  integer :=0;         ---报数
     j   integer:=1;          ---退出顺序
     v_soilder  cur_soilder%ROWTYPE;
BEGIN
      DELETE  FROM  soilders;      
      FOR  i in 1.. v_total  LOOP
             insert into soilders values(i, 0);
      END  LOOP; 
      COMMIT;
      WHILE j<=v_total  LOOP
           OPEN   cur_soilder;
           LOOP
                 FETCH  cur_soilder INTO v_soilder  ;
                 EXIT   WHEN  cur_soilder%NOTFOUND;
                 k:=k+1;        
                 if  mod(k,v_step)=0  then
                       UPDATE  soilders   SET   quit_order = j  
                       WHERE CURRENT OF cur_soilder;
                       j:=j+1;                
                end if;     
           END  LOOP;
           CLOSE  cur_soilder;
           commit;   
       END LOOP;
END;

创建存储过程方便调用

CREATE OR REPLACE PROCEDURE prc_joserph_ring_V2(p_total IN integer,p_step IN integer)
IS
     CURSOR  cur_soilder  IS  
            SELECT * FROM  soilders WHERE quit_order=0 FOR UPDATE;  
     k  integer :=0;         ---报数
     j   integer:=1;          ---退出顺序
     v_soilder  cur_soilder%ROWTYPE;
BEGIN
      DELETE  FROM  soilders;      
      FOR  i in 1.. p_total  LOOP
             insert into soilders values(i, 0);
      END  LOOP; 
      COMMIT;
      WHILE j<=p_total  LOOP
           OPEN   cur_soilder;
           LOOP
                 FETCH  cur_soilder INTO v_soilder  ;
                 EXIT   WHEN  cur_soilder%NOTFOUND;
                 k:=k+1;        
                 if  mod(k,v_step)=0  then
                       UPDATE  soilders   SET   quit_order = j  
                       WHERE CURRENT OF cur_soilder;
                       j:=j+1;                
                end if;     
           END  LOOP;
           CLOSE  cur_soilder;
           commit;   
       END LOOP;
END;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值