约瑟夫环的C语言数组实现
约瑟夫环问题的具体描述是:设有编号为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语言数组实现的更多相关文章
- 约瑟夫环问题-循环链表VS数组
2013-08-18 21:27:50 循环链表.数组解决约瑟夫环问题的比较 注意几点: 循环链表的建立不难,在删除循环链表中元素时,用pCur->next != pCur判断结束: 每一轮计数 ...
- C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析
尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这 ...
- 约瑟夫环(N个人围桌,C语言,数据结构)
约瑟夫环问题(C语言.数据结构版) 一.问题描述 N个人围城一桌(首位相连),约定从1报数,报到数为k的人出局,然后下一位又从1开始报,以此类推.最后留下的人获胜.(有很多类似问题,如猴子选代王等等, ...
- j使用数组实现约瑟夫环 java
我们首先来看一下约瑟夫环问题: 给定m个人,m个人围成一圈,在给定一个数n,从m个人中的第一个人每第n个人便将其除去,求被最后一个出去的人的编号. 思路: 建立一个长度为m+1的数组,将其的内容初始化 ...
- C语言链表实现约瑟夫环问题
需求表达:略 分析: 实现: #include<stdio.h> #include<stdlib.h> typedef struct node { int payload ; ...
- 约瑟夫环问题-Java数组解决
约瑟夫环问题说的是,n个人围成一圈,从第k个人开始沿着一个方向报数,报到第m个人时,第m个人出列,从紧挨着的下一个人(未出列)开始,求整个环中人的出列顺序.下面是我用java实现的解决方法. clas ...
- 约瑟夫环问题 --链表 C语言
总共有m个人在圆桌上,依次报名,数到第n个数的人退出圆桌,下一个由退出人下一个开始继续报名,循环直到最后一个停止将编号输出 #include <stdio.h>#include <s ...
- 数据结构7: 循环链表(约瑟夫环)的建立及C语言实现
链表的使用,还可以把链表的两头连接,形成了一个环状链表,称为循环链表. 和它名字的表意一样,只需要将表中最后一个结点的指针指向头结点,就形成了一个环. 图1 循环链表 循环链表和动态链表相比,唯一的不 ...
- C#实现约瑟夫环问题
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace orde ...
随机推荐
- 测试ssh框架中hibernate的事务
<!-- 配置切面 --> <aop:config> <aop:pointcut expression="execution(* com.xxx.lobs.ma ...
- Angular 5 快速入门与提高
一.概述 尽管被称为Angular5,实际上它只是这个诞生于2012年的前端框架的的第四个版本: 看起来差不多半年就发布一个新版本,不过实际上从重写的版本2开始,开发 接口与核心思想就稳定下来了,并基 ...
- NERDTree 快捷件
key description ctrl+e 打开/关闭文件浏览器 j 向下移动 k 向上移动 o 小写字母o,打开文件或者展开目录 shift+c 即大写字母C,当前选中目录作为根目录 u 上一层目 ...
- NDK 安装小结
建议先看后面的错误,可以先执行那些命令以免出现相关问题. chmod a+x android-ndk-r10c-linux-x86_64.bin ./android-ndk-r10c-linux-x8 ...
- Unity3D学习笔记——Rigdbody刚体组件
Rigdbody刚体组件:必须和碰撞体(Colliders)一起使用,否则会发生穿过的现象.碰撞体(Colliders)不是必须和刚体一起使用. 刚体的作用:使游戏物体能获得重力,接受外界的受力和扭力 ...
- struts2之constant 讲解 (转)
struts.serve.static.browserCache 该属性设置浏览器是否缓存静态内容.当应用处于开发阶段时,我们希望每次请求都获得服务器的最新响应,则可设置该属性为false. stru ...
- python3----split and join
s = "I am fine" s = s.split(" ") print(s) print("%".join(s)) results: ...
- JavaScript API 设计准则
好的 API 设计:在自描述的同时,达到抽象的目标. 设计良好的 API ,开发者可以快速上手,没必要经常抱着手册和文档,也没必要频繁光顾技术支持社区. 流畅的接口 方法链:流畅易读,更易理解 //常 ...
- codevs1058 合唱队形==洛谷P1091 合唱队形
P1091 合唱队形 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的 ...
- Strange Optimization(扩展欧几里得)
Strange Optimization Accepted : 67 Submit : 289 Time Limit : 1000 MS Memory Limit : 65536 KB Str ...