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

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

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知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 SEGMENT
SOURCE DB 01H,02H,03H,04H,05H,06H ;对应人的密码
RESULT DB N DUP(0)
M      DB 00H                     ;输出控制数
M2     DB 00H                     ;输出数据区指示变量
DATA ENDS
SSEG SEGMENT PARA STACK 'STACK'
DB  256 DUP(?)
SSEG ENDS
CODE SEGMENT
      ASSUME CS:CODE,DS:DATA,SS:SSEG,ES:DATA
START: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 LOP4
LOP3: 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,DL
LOP6: ADD AL,1
LOP5: 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 LOP7
LOP8: 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 LOP8
LOP7: MOV DH,CL                    ;k=s
      DEC DL                       ;n--
      CMP DL,1
      JNE LOP1
LOP2: MOV BX,0
      MOV AL,SOURCE[BX]             ;printf(" %d ",a[0])
      MOV BX,N-1
      MOV RESULT[BX],AL
      LEA DI,RESULT
      MOV M,N
LOP0: 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 X2
X1:   CMP AL,61H
      JA X5
      ADD AL,40H
      SUB AL,09H
      MOV BL,AL
      MOV AH,02H
      MOV DL,BL
      INT 21H
      JMP X2
X5:   ADD AL,20H
      MOV BL,AL
      MOV AH,02H
      MOV DL,BL
      INT 21H
X2:   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 X6
X3:   CMP AL,61H
      JA X4
      ADD AL,40H
      SUB AL,09H
      MOV BL,AL
      MOV AH,02H
      MOV DL,BL
      INT 21H
      JMP X6
X4:   ADD AL,20H
      MOV BL,AL
      MOV AH,02H
      MOV DL,BL
      INT 21H
X6:   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


目录
相关文章
|
22天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
34 1
|
4月前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
113 1
|
21天前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
22天前
|
存储 缓存 算法
C语言在实现高效算法方面的特点与优势,包括高效性、灵活性、可移植性和底层访问能力
本文探讨了C语言在实现高效算法方面的特点与优势,包括高效性、灵活性、可移植性和底层访问能力。文章还分析了数据结构的选择与优化、算法设计的优化策略、内存管理和代码优化技巧,并通过实际案例展示了C语言在排序和图遍历算法中的高效实现。
41 2
|
22天前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
39 1
|
22天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
54 1
|
1月前
|
存储 算法 数据管理
C语言算法复杂度
【10月更文挑战第20天】
C语言算法复杂度
|
2月前
|
存储 算法 C语言
【C语言】二分查找算法
【C语言】二分查找算法
|
2月前
|
算法 Java
数据结构与算法学习六:单向环形链表应用实例的约瑟夫环问题
这篇文章通过单向环形链表的应用实例,详细讲解了约瑟夫环问题的解决方案,并提供了Java代码实现。
25 0
|
2月前
|
Linux C语言 iOS开发
MacOS环境-手写操作系统-06-在mac下通过交叉编译:C语言结合汇编
MacOS环境-手写操作系统-06-在mac下通过交叉编译:C语言结合汇编
45 0