约瑟夫环的C语言和86/88汇编非递归算法

来源:互联网 发布:淘宝照相技巧 编辑:程序博客网 时间:2024/06/05 04:27

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
我这个解决方案是,从1到n进行编号,打印出这些人的编号的出列顺序。

我是第一个发表对约瑟夫环的非递归算法(采用数组实现),发表时间是2006年6月。是对一个2004年的一个百度提问的解答。现在已经找不到那个帖子了。当时我给的结解决方案是用宏制定输入的人数和报数上线。
约瑟夫环的数组实现方法,虽然代码比代码多些,但是很好理解,并且理论上的解析范围比递归算法大的多(像汉诺塔问题用递归,达到63层跌代以上程序就跑飞了)。现在N多人都是改编的我的方案。
C语言实现约瑟夫环:
/***********************************************************
该程序是用C语言实现约瑟夫环的高效算法,它比链表有更高的空间和时间效率。
但它只支持最多人数为128人,若想实现支持更多人数只需要修改数组a的大小。
***********************************************************/

#include<stdio.h>main(){    int a[128],b[128];    int i,code,k,m,n,s,t;    printf("输入初始报数上限值m:");    scanf("%d",&m);     if(m <= 0)    {        return;    }    printf("输入人数n:");     scanf("%d",&n);    for(i=0;i<n;i++)    {        scanf("%d",&code);         b[i]=code;    }    printf("指定开始报数人的编号t:");//第一个参照人的编号为1    scanf("%d",&t); k=0;    for(i=t-1;i<n;i++)a[k++]=b[i];    for(i=0;i<t-1;i++)a[k++]=b[i];k=0;    while(n!=1){        s=m%n;        if(k!=0)s=(s+k-2)%n+1;                    printf(" %d ",a[s-1]);            for(i=s-1;i<n-1;i++)a[i]=a[i+1];              k=s;    n--;    }    printf(" %d ",a[0]);}汇编实现:  这个汇编的方案我当时写了没有发表,相信没有其它人比我先发表这个方案吧!本方案已经运行测试。;本程序是用汇编语言实现约约瑟夫环;它最大支持255人的报数和人数;它的密码要事先要在数据段初始化;它的例子是从第一个报数为顺序进行密码编码的,当然可以自己编码;认数和报数要事先要初始化;它支持在DOS下运行并显示结果;软件需求:LINK.EXE和MASM.EXE          M1 EQU 6                ;初始报数上限值m:          N EQU 6                 ;人数n:DATA SEGMENTSOURCE DB 01H,02H,03H,04H,05H,06H ;对应人的密码RESULT DB N DUP(0)M      DB 00H                     ;输出控制数M2     DB 00H                     ;输出数据区指示变量DATA ENDSSSEG SEGMENT PARA STACK 'STACK'DB  256 DUP(?)SSEG ENDSCODE SEGMENT      ASSUME CS:CODE,DS:DATA,SS:SSEG,ES:DATASTART:PUSH DS      XOR AX,AX      PUSH AX      MOV AX,DATA      MOV DS,AX      MOV ES,AX            MOV DH,0                     ;k=0      MOV DL,N      CMP DL,1      JZ LOP2                     ;while(n!=1){LOP1: MOV AL,M1                    ;s=m%n      CMP AL,DL      JB LOP4LOP3: SUB AL,DL      CMP AL,DL      JNB LOP3     LOP4: CMP DH,0            ;if(k!=0)s=(s+k-2)%n+1      JE  LOP5      ADD AL,DH      SUB AL,2          CMP AL,DL      JB LOP6      SUB AL,DLLOP6: ADD AL,1LOP5: MOV AH,0       MOV CL,AL         ;CL---s      DEC AL            ;AL---s-1      MOV BX,AX      MOV AL,SOURCE[BX] ;printf(" %d ",a[s-1])      MOV BL,M2      MOV BH,0      MOV RESULT[BX],AL      INC BL      MOV M2,BL      MOV AL,CL      SUB AL,1      MOV CH,AL        ;for(i=s-1;i<n-1;i++)a[i]=a[i+1]      MOV AL,DL        ;AL--n      SUB AL,1         ;AL--n-1      CMP CH, AL       ;CH--i=s-1           JNB LOP7LOP8: MOV AL,CH      MOV AH,0      MOV BX,AX      MOV AL,SOURCE[BX+1]      MOV SOURCE[BX],AL          INC CH      MOV AL,DL      SUB AL,1      CMP CH, AL      ;i<n-1      JB LOP8LOP7: MOV DH,CL                    ;k=s      DEC DL                       ;n--      CMP DL,1      JNE LOP1LOP2: MOV BX,0      MOV AL,SOURCE[BX]             ;printf(" %d ",a[0])      MOV BX,N-1      MOV RESULT[BX],AL      LEA DI,RESULT      MOV M,NLOP0: MOV AL,[DI]      AND AL,0F0H      MOV CL,4      SHR AL,CL      CMP AL,9      JA X1      ADD AL,30H      MOV BL,AL      MOV AH,02H      MOV DL,BL      INT 21H      JMP X2X1:   CMP AL,61H      JA X5      ADD AL,40H      SUB AL,09H      MOV BL,AL      MOV AH,02H      MOV DL,BL      INT 21H      JMP X2X5:   ADD AL,20H      MOV BL,AL      MOV AH,02H      MOV DL,BL      INT 21HX2:   MOV AL,[DI]      AND AL,0FH      CMP AL,9      JA X3      ADD AL,30H      MOV BL,AL      MOV AH,02H      MOV DL,BL      INT 21H      JMP X6X3:   CMP AL,61H      JA X4      ADD AL,40H      SUB AL,09H      MOV BL,AL      MOV AH,02H      MOV DL,BL      INT 21H      JMP X6X4:   ADD AL,20H      MOV BL,AL      MOV AH,02H      MOV DL,BL      INT 21HX6:   INC DI      DEC M      JNZ LOP0      RET      CODE ENDS      END START

我解决约瑟夫环的非递归算法的时间见图片:
这里写图片描述
我做的再window xp下运行我的汇编程序是在我2005年上学时做的,幸亏当时写了操作手册,不然现在我还运行不了呢!修改操作手册在window7(64位操作系统)上操作成功。
运行结果如下:
这里写图片描述

该问题的代码运行操作见文章:86/88汇编代码的运行调试 http://blog.csdn.net/jia12216/article/details/46895619
三级pc上机试题的可运行代码资源包的下载地址是:http://download.csdn.net/detail/jia12216/8902455

0 0