josephus问题 链表。我的代码哪里有错?结果输不出。

继续笔试准备ing……分享一下昨天做到的其中一题,其实题目很老,也做过n遍了,但复习起来也是颇有韵味,同时还发现另一种妙解,感觉不错的。问题描述:&&&&&&约瑟夫环问题(Josephus)&&&&&&用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。(约瑟夫环问题 Josephus)解法一(My Solution):&&&&&&思想:建立一个有N个元素的循环链表,然后从链表头开始遍历并记数,如果计数i==m(i初始为1)踢出元素,继续循环,当当前元素与下一元素相同时退出循环。代码:
&&1&/*&&2&&约瑟夫环问题(Josephus)&&3&&用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。(约瑟夫环问题&Josephus)&&4&&Code&By&Eric&Yang&2009&&5&&&&6&*/&&7&#include&&stdio.h&&&8&#include&&stdlib.h&&&9&&10&//&链表节点&11&typedef&struct&_RingNode&12&{&13&&&&&int&&&//&位置&14&&&&&struct&_RingNode&*&15&}RingNode,&*RingNodeP&16&&17&//&创建约瑟夫环,pHead:链表头指针,count:链表元素个数&18&void&CreateRing(RingNodePtr&pHead,&int&count)&19&{&20&&&&&RingNodePtr&pCurr&=&NULL,&pPrev&=&NULL;&21&&&&&int&i&=&<span style="color: #;&22&&&&&pPrev&=&pH&23&&&&&while(--count&&&<span style="color: #)&24&&&&&{&25&&&&&&&&&pCurr&=&(RingNodePtr)malloc(sizeof(RingNode));&26&&&&&&&&&i++;&27&&&&&&&&&pCurr-&pos&=&i;&28&&&&&&&&&pPrev-&next&=&pC&29&&&&&&&&&pPrev&=&pC&30&&&&&}&31&&&&&pCurr-&next&=&pH&&//&构成环状链表&32&}&33&&34&void&PrintRing(RingNodePtr&pHead)&35&{&36&&&&&RingNodePtr&pC&37&&&&&printf("%d",&pHead-&pos);&38&&&&&pCurr&=&pHead-&&39&&&&&while(pCurr&!=&NULL)&40&&&&&{&41&&&&&&&&&if(pCurr-&pos&==&<span style="color: #)&42&&&&&&&&&&&&&break;&43&&&&&&&&&printf("\n%d",&pCurr-&pos);&44&&&&&&&&&pCurr&=&pCurr-&&45&&&&&}&46&}&47&&48&void&KickFromRing(RingNodePtr&pHead,&int&m)&49&{&50&&&&&RingNodePtr&pCurr,&pP&51&&&&&int&i&=&<span style="color: #;&&&&//&计数&52&&&&&pCurr&=&pPrev&=&pH&53&&&&&while(pCurr&!=&NULL)&54&&&&&{&55&&&&&&&&&if&(i&==&m)&56&&&&&&&&&{&57&&&&&&&&&&&&&//&踢出环&58&&&&&&&&&&&&&printf("\n%d",&pCurr-&pos);&&&&//&显示出圈循序&59&&&&&&&&&&&&&pPrev-&next&=&pCurr-&&60&&&&&&&&&&&&&free(pCurr);&61&&&&&&&&&&&&&pCurr&=&pPrev-&&62&&&&&&&&&&&&&i&=&<span style="color: #;&63&&&&&&&&&}&64&&&&&&&&&pPrev&=&pC&65&&&&&&&&&pCurr&=&pCurr-&&66&&&&&&&&&if&(pPrev&==&pCurr)&67&&&&&&&&&{&68&&&&&&&&&&&&&//&最后一个&69&&&&&&&&&&&&&printf("\n%d",&pCurr-&pos);&&&&//&显示出圈循序&70&&&&&&&&&&&&&free(pCurr);&71&&&&&&&&&&&&&break;&72&&&&&&&&&}&73&&&&&&&&&i++;&74&&&&&}&75&}&76&&77&int&main()&78&{&79&&&&&int&m&=&<span style="color: #,&n&=&<span style="color: #;&80&&&&&RingNodePtr&pHead&=&NULL;&81&&&&&printf("---------------Josephus&Ring---------------\n");&82&&&&&printf("N(person&count)&=&");&83&&&&&scanf("%d",&&n);&84&&&&&printf("M(out&number)&=&");&85&&&&&scanf("%d",&&m);&86&&&&&if(n&&=&<span style="color: #&||&m&&=&<span style="color: #)&87&&&&&{&88&&&&&&&&&printf("Input&Error\n");&89&&&&&&&&&system("pause");&90&&&&&&&&&return&<span style="color: #;&91&&&&&}&92&&&&&//&建立链表&93&&&&&pHead&=&(RingNodePtr)malloc(sizeof(RingNode));&94&&&&&pHead-&pos&=&<span style="color: #;&95&&&&&pHead-&next&=&NULL;&96&&&&&CreateRing(pHead,&n);&97&#ifdef&_DEBUG&98&&&&&PrintRing(pHead);&99&#endif<span style="color: #0&<span style="color: #1&&&&&//&开始出圈<span style="color: #2&&&&&printf("\nKick&Order:&");<span style="color: #3&&&&&KickFromRing(pHead,&m);&&&&<span style="color: #4&&&&&printf("\n");<span style="color: #5&&&&&system("pause");<span style="color: #6&&&&&return&<span style="color: #;<span style="color: #7&}<span style="color: #8&解法二(From Net):&&&&&&思想:归纳为数学性问题。原文说的很好,还是直接Copy吧,因为搜索半天也没有找到原作者,所以无法添加引用地址了,如果这位大哥看到这里,请告知与我,小弟立刻加入引用链接:)无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。为了讨论方便,先把问题稍微改变一下,并不影响原意:问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):& k& k+1& k+2& ... n-2, n-1, 0, 1, 2, ... k-2并且从k开始报0。现在我们把他们的编号做一下转换:k&&&& --& 0k+1&& --& 1k+2&& --& 2......k-2&& --& n-2k-1&& --& n-1变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x'=(x+k)%n如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]递推公式f[1]=0;f[i]=(f[i-1]+m)%i;& (i&1)有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1由于是逐级递推,不需要保存每个f[i],程序也是异常简单:
&1&#include&&stdio.h&&2&int&main()&3&{&4&&&&&int&n,&m,&i,&s&=&<span style="color: #;&5&&&&&printf&("N&M&=&");&6&&&&&scanf("%d%d",&&n,&&m);&7&&&&&for&(i&=&<span style="color: #;&i&&=&n;&i++)&8&&&&&{&9&&&&&&&&&s&=&(s&+&m)&%&i;<span style="color: #&&&&&}<span style="color: #&&&&&printf&("\nThe&winner&is&%d\n",&s+<span style="color: #);<span style="color: #&}这个算法的时间复杂度为O(n),相对于模拟算法已经有了很大的提高。算n,m等于一百万,一千万的情况不是问题了。可见,适当地运用数学策略,不仅可以让编程变得简单,而且往往会成倍地提高算法执行效率。相比之下,解法二的优越性不言而喻,同时说明数学确实很重要。
阅读(...) 评论()我的港版PS4兑换NBA2K15的特典提示输入代码错误,可是我是对着输入的请问怎么回事?_百度知道
我的港版PS4兑换NBA2K15的特典提示输入代码错误,可是我是对着输入的请问怎么回事?
亲,2K15的特典兑换码,需要去特点卡上的网站兑换
其他类似问题
为您推荐:
其他3条回答
字母用小写,5个一组中间加横线-我试过了,有用请给分,谢谢
网络问题或者你眼睛问题
我都对了一个晚上了你说我眼睛有问题那就好笑了
&#47;&#47;&#47;i&#47;sys&#47;jump?un=%CCK%B6%EDKicZlh& onclick=&Stats.sendRequest(&#39;fr=tb0_forum&st_mod=pb&st_value=atlink&#39;);& onmouseover=&showattip(this)& onmouseout=&hideattip(this)& username=&%CCK%B6%EDKicZlh& target=&_blank& class=&at&&蘇俄KicZlh
:楼主解决了吗?我今天的死或生的特典码也出错,对了1个小时,我就艹了。。。。
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁我在编写C语言代码的时候,有时候代码会有一些逻辑上的错误,就是代码可以运行,但得不到正确的结果._百度知道
我在编写C语言代码的时候,有时候代码会有一些逻辑上的错误,就是代码可以运行,但得不到正确的结果.
所以 我应该怎么 找到那段 不合逻辑的代码呢·?
但是结果就是2。老手最郁闷的事情莫过于新手问为什么我的程序可以运行但是却得不到自己的结果了吧.。你不可能一下子就得到自己想要的结果。没有开发不调试的,不会把它故意设计成每小时或者没几天崩溃几次吧。而且可以很好的运行。开发人员都知道。如果:老师让你输出。为什么得不到自己想要的结果。如果你用过Windows98就应该知道那时候系统经常崩溃的新手最郁闷的事情莫过于程序可以运行但是却得不到自己的结果了吧,而且我猜你用的是Windows:1你写个程序输出。gdb。不崩溃的时候,使用它:那是因为你的程序根本就没有写对比如。OK,爱上它:你天天用操作系统。不会debug:2你的代码当然编译不会出错。但是微软设计的时候。尤其是比较大的程序。(gdb *nix平台的,修改。太简单了逻辑错误就得调试了这个世界上只有调试不开发的,程序不也是正常运行么.永远都不会是1:再也没有比修改语法错误再简单的了直接看看编译器报的错。,因为你就让他输出的2,结果怎么会是1呢.学习它,看看第几行。永远都不是程序员。比如
其他类似问题
为您推荐:
其他2条回答
学会设置断点
一步步调试 你会找到不是想要的那个变量 然后在附近查看逻辑上的问题
学会调试,一般的逻辑问题调试了就可以找到解决方法了。可以自己到网上找找调试的方法,实在不会就让别人检查下程序,比如发到c语言吧或者cQQ群里求助
c语言的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁★约瑟夫问题(Josephus Problem)――C++代码实现★_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
★约瑟夫问题(Josephus Problem)――C++代码实现★
上传于||文档简介
&&约&#8203;瑟&#8203;夫&#8203;问&#8203;题&#8203;(&#8203;J&#8203;o&#8203;s&#8203;e&#8203;p&#8203;h&#8203;u&#8203;s&#8203; &#8203;P&#8203;r&#8203;o&#8203;b&#8203;l&#8203;e&#8203;m&#8203;)&#8203;―&#8203;―&#8203;C&#8203;+&#8203;+&#8203;代&#8203;码&#8203;实&#8203;现
阅读已结束,如果下载本文需要使用
想免费下载本文?
你可能喜欢谁帮我看看代码是哪里有错啊?_百度知道
谁帮我看看代码是哪里有错啊?
用VS2005调试的:#include&iostream&#include&cmath&template&class T&struct Node{ T struct Node&T&*};template&class T&class Josephus{public: Josephus() {
rear=new Node&T&;
rear-&next= }&#47;&#47;无参构造函数 Josephus(T a[],int n);&#47;&#47;有参构造函数,实用含有n个元素的数组a初始化单链表 ~Josephus();&#47;&#47;析构函数 T *Get(int i);&#47;&#47;获取线性表中第i个位置上的元素 T Delete(int i);&#47;&#47;删除线性表第i个元素,并将该元素返回private:
T a[]; Node&T& *&#47;&#47;尾指针};template&class T&Josephus&T&::Josephus(T供涪垛皇艹郝讹酮番捆 a[],int n)&#47;&#47;有参构造函数{ front=new Node&T&; front-&next=NULL; for(int i=n-1;i&=0;i--) {
Node&T& *s=new Node &T&;&#47;&#47;建立新节点
s-&data=a[i];&#47;&#47;将a[i]写入到新节点的数据域
s-&next=front-&&#47;&#47;修改新节点的指针域
front-&next=s;&#47;&#47;修改头结点的指针域,将新节点加入到链表中 } rear=new Node&T&; rear-&next=}template&class T&Josephus&T&::~Josephus()&#47;&#47;析构函数{ Node&T& *p =&#47;&#47;初始化工作指针p while(p)&#47;&#47;判断要释放的节点是否存在 {
front=p;&#47;&#47;暂存要释放的节点
p=p-&&#47;&#47;移动工作指针
&#47;&#47;释放节点 }}template&class T&Node&T&*Josephus&T&::Get(int i)&#47;&#47;获取线性表第i个位置上的元素{ Node&T& *p=front-&&#47;&#47;初始化工作指针 int j=1;&#47;&#47;初始化计数器 while(p&&j!=i)&#47;&#47;两个条件都满足,则继续循环 {
p=p-&&#47;&#47;工作指针后移
j++; } &#47;&#47;查找到第i个元素返回地址,或为找到元素返回}template&class T&T Josephus&T&::Delete(int i)&#47;&#47;删除线性表第i个元素,并将该元素返回{ Node&T& *p=&#47;&#47;初始化工作指针 if(i!=1) p=Get(i-1);&#47;&#47;若不是在第一个位置插入,得到第i-1个元素的地址 Node&T& *q=p-& p-&next=q-& T x=q-&
}void main(){ int n=20,m=4; int a[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; Josephus test(a[0],20);}
我有更好的答案
void main(){ int n=20,m=4; i供涪垛皇艹郝讹酮番捆nt a[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; Josephus test(a[0],20);}你的主函数m不应该大写么??void Main
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 josephus问题c 代码 的文章

 

随机推荐