约瑟夫环问题的具体描述是:设有编号为1,2,……,n的n个(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,才从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,知道剩余1个人为止。当任意给定n和m后,设计算法求n个人出圈的次序。

一开始看到这这个题目就是觉得这是一个环形的,想到了用链表和用指针,然后看题目的要求是使用数组实现。就先暂时放弃用链表的办法,用数组实现之后再用链表来实现。

一开始的思路是:

1、建立一个长度为n的数组。

2、取出位置编号为(i+1)*m的数显示,将位置编号为(i+1)*m的数置0;

3、第一轮取完之后的数再组成一个新的数组,用2的办法再取;

4、重复3的操作,最后剩下m-1个数字。

经过实际编程调试发现这个办法很难实现,效率特别低,容易出错,仅仅是第一轮取完数字再组成一个新的数组就很费劲了,如果数字比较少的话可以直接算出来,如果数据量大,就很麻烦。

后来,就反思一开始的思路其实就是模拟了一个“环“,通过好多数组来拼接一个环。这样就很麻烦,逻辑上也很混乱,最后也是看了其他人的代码,觉得用指针的思想到最后一个数的时候跳到第一个就可以了。最早的时候我也有想到过用指针的思想去解决,但是不会用,主要原因是因为我不知道有这样i = (i + m -1) % n一个公式,公式中i就是出圈的那个数字,知道了这个公式之后就是每次需要把出圈的数字删除了就可以,继续用这个公式找到下一个需要出圈的数字。最后找到只剩一个的时候跳出,中间如果找到某一时刻数组的最后一个数字的时候跳到第一个就可以了,这样就形成了一个环。

根据这个思路完成了下边的这个程序,这个程序是7个数,报3出圈。

#include <stdio.h>

#include <string.h>

 int main()

 {

     int m = ;

     int n = ;

        int a[] = {,,,,,,};

        int i;

        int j;

     for(i = ; i < n; i++)

     {

         a[i] = i+;

     }

     while (n > )

     {

         i = (i + m - ) % n;

         printf("第一个出圈的是%d\n",a[i]);

         for(j = i+; j < n; j++)

         {

             a[j-] = a[j];

         }

         n--;

         if(i == n)

         {

             i = ;

         }

     }

     printf("最后剩下的是%d\n", a[i]);

     return ;

 }

上边这段代码在调试的过程中出了一个非常低级的错误,编译完成后开始运行的时候发现,程序确实在运行但是什么都不显示,就开始一点一点的调试,发现问题出在了循环部分,发现循环内部是没有问题的,按照逻辑分析是可以跳出循环的,而且循环中是有显示的,如果不能跳出循环肯定会连续的显示,后来就意识到是没有进入到循环中,又看了很多遍程序才发现是在while(n > 1)这句话后边加了“;”号,这样的低级错误确实不应该,编程太少,所以找到错误花了比较长的时间,还是需要多自主编程,积累经验。

根据上边的程序我也进行了一些简单的修改,能够实现定制,也就是你可以自己设置输入的m,n值,代码如下。

#include <stdio.h>

#include <string.h>

#define N 100

int main()

  {

      int m;

      int n;

         printf("请输入总人数n \n");

         scanf("%d",&n);

         printf("请输入报的数m \n");

         scanf("%d",&m);

      int a[N] = {};

      int i;

      int j;

         int k = ;

         for(i = ; i < n; i++)

      {

          a[i] = i+;

      }

      while (n > )

      {

          i = (i + m - ) % n;

                k++;

                printf("第%d个出圈的是%d\n",k,a[i]);

          for(j = i+; j < n; j++)

          {

              a[j-] = a[j];

          }

          n--;

          if(i == n)

                {

                    i = ;

          }

      }

      printf("最后剩下的时%d\n", a[i]);

      return ;

  }

有了第一个代码,第二个随机输入就好实现了,但是在编程过程中还是出现了点问题,因为人数是随机输入的,那么n的值就没办法确定了,定义数组的时候a[n]这种方式是错误的,因此需要定义一个较大的数组,数组的后半段在程序中不使用就可以了。另外scanf函数在使用的时候要记得加”&”,不然会出现段错误,如果调试过程中出现了段错误,可以看看代码中是不是忘记加“&”符号了。

约瑟夫环也可以用链表的方式来实现,接下来会再用链表的方式来实现以下,后边的博客会实现。

这是新年之后的第一篇博客,新年之后能够快速的进入学习状态是一个好的开端。新一年,同时又是编程学习的新的重要的阶段,开始自己写程序,摆脱抄程序的过程。新年中也反思了去年的学习,专注力不够是一个很大的问题,原因在于上进心不足,眼界不够,看不到未来让我觉得迷茫,懈怠。今年是我人生的一个转折点,提高专注力,用好每天的学习时间,把最能专心学习的时间用在学习上,加强自律。

约瑟夫环的C语言数组实现的更多相关文章

  1. 约瑟夫环问题-循环链表VS数组

    2013-08-18 21:27:50 循环链表.数组解决约瑟夫环问题的比较 注意几点: 循环链表的建立不难,在删除循环链表中元素时,用pCur->next != pCur判断结束: 每一轮计数 ...

  2. C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析

    尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这 ...

  3. 约瑟夫环(N个人围桌,C语言,数据结构)

    约瑟夫环问题(C语言.数据结构版) 一.问题描述 N个人围城一桌(首位相连),约定从1报数,报到数为k的人出局,然后下一位又从1开始报,以此类推.最后留下的人获胜.(有很多类似问题,如猴子选代王等等, ...

  4. j使用数组实现约瑟夫环 java

    我们首先来看一下约瑟夫环问题: 给定m个人,m个人围成一圈,在给定一个数n,从m个人中的第一个人每第n个人便将其除去,求被最后一个出去的人的编号. 思路: 建立一个长度为m+1的数组,将其的内容初始化 ...

  5. C语言链表实现约瑟夫环问题

    需求表达:略 分析: 实现: #include<stdio.h> #include<stdlib.h> typedef struct node { int payload ; ...

  6. 约瑟夫环问题-Java数组解决

    约瑟夫环问题说的是,n个人围成一圈,从第k个人开始沿着一个方向报数,报到第m个人时,第m个人出列,从紧挨着的下一个人(未出列)开始,求整个环中人的出列顺序.下面是我用java实现的解决方法. clas ...

  7. 约瑟夫环问题 --链表 C语言

    总共有m个人在圆桌上,依次报名,数到第n个数的人退出圆桌,下一个由退出人下一个开始继续报名,循环直到最后一个停止将编号输出 #include <stdio.h>#include <s ...

  8. 数据结构7: 循环链表(约瑟夫环)的建立及C语言实现

    链表的使用,还可以把链表的两头连接,形成了一个环状链表,称为循环链表. 和它名字的表意一样,只需要将表中最后一个结点的指针指向头结点,就形成了一个环. 图1 循环链表 循环链表和动态链表相比,唯一的不 ...

  9. C#实现约瑟夫环问题

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace orde ...

随机推荐

  1. apache gzip

    1.首先启动模块mod_deflate.so和mod_headers.so 2.httpd.conf #文件缓存时间配置<FilesMatch ".(flv|gif|jpg|jpeg| ...

  2. https原理与实践

    HTTPS 原理与证书实践   分类: Web应用   1.1 网络安全知识 1.1.1 网结安全出现背景 网络就是实现不同主机之间的通讯,网络出现之初利用TCP/IP协议簇的相关协议概念,已经满足了 ...

  3. Laragon集成开发环境+配置Xdebug+postman运行Xdebug

    [ Laravel 5.5 文档 ] 快速入门 —— 使用 Laragon 在 Windows 中搭建 Laravel 开发环境:http://laravelacademy.org/post/7754 ...

  4. 集合 Vector ArrayList 集合一

    集合是存储对象的,与对象数组不同,集合可以自动的扩大自己的容量,像StringBuffer一样,存储的对象类型可以不一致,(object数组). 方法: add();remove();get();se ...

  5. mysqldump: Got error: 1045

    问题:最近备份mysql然后在执行mysqldump的时候提示权限和密码有问题 报错: Warning: Using a password on the command line interface ...

  6. Java 基础巩固:IO

    在学习IO的时候发现IO的类太多,如InputStream下面就用ReaderInputStream.InputStreamBuffer等等, 还用Reader.Writer.OutputStream ...

  7. LightOJ1089

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26806 题目大意:略 题目思路:前缀和与离散化 可用线段树做,但是 ...

  8. 【BZOJ2793】[Poi2012]Vouchers 调和级数

    [BZOJ2793][Poi2012]Vouchers Description 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个.正整 ...

  9. 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree

    [BZOJ1941][Sdoi2010]Hide and Seek Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了 ...

  10. FFF at Valentine(强连通分量缩点+拓扑排序)

    FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...