约瑟夫环问题的具体描述是:设有编号为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. knockout+weui+zepto

    主文件wxapp.ts 1>在ts中,建议继承componentui //操作菜单表 actionsheet showactionsheet { title 上拉菜单标题 btns 操作组 建议 ...

  2. [Android]ListView & ViewPager & GridView 常见问题解决方法

    1. ViewPager左右滚动到两边时的渐变色,若想禁止,可以在布局文件中配置:android:overScrollMode="never" 2. ListView,GridVi ...

  3. java 通过Apache poi导出excel代码demo实例

    package com.zuidaima.excel.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutput ...

  4. sqoop1.4.4从oracle导数据到hive中

    sqoop从oracle定时增量导入数据到hive 感谢: http://blog.sina.com.cn/s/blog_3fe961ae01019a4l.htmlhttp://f.dataguru. ...

  5. python3----split and join

    s = "I am fine" s = s.split(" ") print(s) print("%".join(s)) results: ...

  6. python中json操作

    1.写操作.json文件dumps().dump()函数 d = { 'zll': { 'addr': '北京', 'age': 28 }, 'ljj': { 'addr': '北京', 'age': ...

  7. ViewPager页面切换特效

    ViewPager页面切换特效如下效果 看效果: 效果1: 效果2: 下面就开始讲解如何实现这两个页面翻转效果 1.首先你得会ViewPager控件的使用(废话!现在还有人不会使用吗???!!) 2. ...

  8. P2424 约数和

    题目背景 Smart最近沉迷于对约数的研究中. 题目描述 对于一个数X,函数f(X)表示X所有约数的和.例如:f(6)=1+2+3+6=12.对于一个X,Smart可以很快的算出f(X).现在的问题是 ...

  9. 图片热区——map的用法

    <area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: 1 & ...

  10. py 与 pyc 文件

    本文要说明的问题 pyc 文件是什么 pyc 文件的作用 py 与 pyc 文件冲突 pyc 文件是什么 当 py 文件加载后,py 文件被二进制编码成 pyc 文件.py 文件的修改时间被记录到 p ...