在本文中,我们将详细介绍PHP实现约瑟夫环问题的方法分析的各个方面,并为您提供关于约瑟夫环php的相关解答,同时,我们也将为您带来关于C#实现约瑟夫环、c++约瑟夫环问题、C语言基于循环链表解决约瑟夫
在本文中,我们将详细介绍PHP实现约瑟夫环问题的方法分析的各个方面,并为您提供关于约瑟夫环 php的相关解答,同时,我们也将为您带来关于C#实现约瑟夫环、c++约瑟夫环问题、C语言基于循环链表解决约瑟夫环问题的方法示例、c语言实现约瑟夫环的有用知识。
本文目录一览:PHP实现约瑟夫环问题的方法分析(约瑟夫环 php)
本文实例讲述了PHP实现约瑟夫环问题的方法。分享给大家供大家参考,具体如下:
一、概述
先来看看网上比较常见的约瑟夫环问题描述:约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
二、实现代码
1. 循环
function circle($arr,$idx,$k){ for($i=0;$i<$idx;$i++){ $tmp = array_shift($arr); array_push($arr,$tmp); } $j = 1; while(count($arr) > 0){ $tmp = array_shift($arr); if($j++%$k == 0){ echo $tmp."\n"; }else{ array_push($arr,$tmp); } } } $arr = array(1,2,3,4,5,6,7,8,9,10,11,12); $idx = 3; $k = 4; circle($arr,$idx,$k);
运行结果:
7 11 3 8 1 6 2 10 9 12 5 4
2. 递归
function circle($arr,$idx,$k){ $len = count($arr); $i = 1; if($len == 1){ echo $arr[0]."\n"; return ; } else { while($i++ < $k){ $idx++; $idx = $idx%$len; } echo $arr[$idx]."\n"; array_splice($arr,$idx,1); circle($arr,$idx,$k); } } $arr = [1,2,3,4,5,6,7,8,9,10,11,12]; $idx = 3; $k = 4; circle($arr,$idx,$k);
运行结果:
7 11 3 8 1 6 2 10 9 12 5 4
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP数据结构与算法教程》、《php程序设计算法总结》、《php字符串(string)用法总结》、《PHP数组(Array)操作技巧大全》、《PHP常用遍历算法与技巧总结》及《PHP数学运算技巧总结》
希望本文所述对大家PHP程序设计有所帮助。
- php解决约瑟夫环示例
- 约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
- PHP使用栈解决约瑟夫环问题算法示例
- PHP基于递归实现的约瑟夫环算法示例
- PHP实现的基于单向链表解决约瑟夫环问题示例
- php基于环形链表解决约瑟夫环问题示例
- php实现约瑟夫问题的方法小结
- php约瑟夫问题解决关于处死犯人的算法
- PHP基于关联数组20行代码搞定约瑟夫问题示例
- php使用环形链表解决约瑟夫问题完整示例
- php解决约瑟夫环算法实例分析
C#实现约瑟夫环
代码如下
using UnityEngine;
public class Test : MonoBehaviour
{
class Node<T>
{
private T value;
public T Value()
{
return value;
}
private Node<T> nextNode;
public Node<T> NextNode()
{
return nextNode;
}
public Node(T v)
{
value = v;
nextNode = null;
}
public void SetNext(Node<T> node)
{
nextNode = node;
}
}
class JLinkedList<T>
{
public Node<T> head;
private int count;
public Node<T> current;
public JLinkedList()
{
head = null;
count = 0;
current = null;
}
public void Append(T v)
{
Node<T> node = new Node<T>(v);
if (count == 0)
{
head = node;
node.SetNext(head);
head.SetNext(node);
}
else
{
node.SetNext(head);
current.SetNext(node);
}
current = node;
count++;
}
public void KillNext()
{
current = current.NextNode().NextNode();
Debug.Log(current.NextNode().Value());
current.SetNext(current.NextNode().NextNode());
count--;
}
public void StartToKill()
{
while(count > 0)
{
KillNext();
}
}
}
// Start is called before the first frame update
void Start()
{
JLinkedList<int> list = new JLinkedList<int>();
for(int i = 1; i < 42; i ++)
{
list.Append(i);
}
list.StartToKill();
}
}
c++约瑟夫环问题
//约瑟问题
//问题背景,一共有30个人,围成环圈,开始报数,数到9的人被丢弃,一直到剩下15个人 为止
#include<iostream>
using namespace std;
int main()
{
int all[30];
int yijiao[15];
int jidu[15];
int i,j,k,yijiao_count,yijiao_index,jidu_count;
for(i=0;i<30;i++)
all[i]=i+1;
i=0;
k=0;
yijiao_count=0;
yijiao_index=0;
jidu_count=0;
while(yijiao_count<15)
{
if(all[i]!=0)
k++;
if(k==9)
{
yijiao[yijiao_index]=all[i];
yijiao_index++;
all[i]=0;
k=0;
yijiao_count++;
}
i++;
if(i==30)
i=0;
}
for(i=0;i<30;i++)
{
if(all[i]!=0)
{
jidu[jidu_count]=all[i];
jidu_count++;
}
}
cout<<"异教徒的序号为:"<<endl;
for(i=0;i<15;i++)
{
cout<<yijiao[i]<<" ";
}
cout<<endl<<"基督教徒的序号为:"<<endl;
for(i=0;i<15;i++)
{
cout<<jidu[i]<<" ";
}
cout<<endl;
return 0;
}
C语言基于循环链表解决约瑟夫环问题的方法示例
本文实例讲述了C语言基于循环链表解决约瑟夫环问题的方法。分享给大家供大家参考,具体如下:
概述:
约瑟夫环问题,是一个经典的循环链表问题,题意是:已知 n 个人(以编号1,2,3,…,n分别表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列;他的下一个人又从 1 还是顺时针开始报数,数到 m 的那个人又出列;依次重复下去,要求找到最后出列的那个人。
例如有 5 个人,要求从编号为 3 的人开始,数到 2 的那个人出列:
出列顺序依次为:
编号为 3 的人开始数 1,然后 4 数 2,所以 4 先出列;
4 出列后,从 5 开始数 1,1 数 2,所以 1 出列;
1 出列后,从 2 开始数 1,3 数 2,所以 3 出列;
3 出列后,从 5 开始数 1,2 数 2,所以 2 出列;
最后只剩下 5 自己,所以 5 出列。
代码实现:
#include <stdio.h> #include <stdlib.h> typedef struct node{ int number; struct node * next; }person; person * initLink(int n){ person * head=(person*)malloc(sizeof(person)); head->number=1; head->next=NULL; person * cyclic=head; for (int i=2; i<=n; i++) { person * body=(person*)malloc(sizeof(person)); body->number=i; body->next=NULL; cyclic->next=body; cyclic=cyclic->next; } cyclic->next=head;//首尾相连 return head; } void findAndKillK(person * head,int k,int m){ person * tail=head; //找到链表第一个结点的上一个结点,为删除操作做准备 while (tail->next!=head) { tail=tail->next; } person * p=head; //找到编号为k的人 while (p->number!=k) { tail=p; p=p->next; } //从编号为k的人开始,只有符合p->next==p时,说明链表中除了p结点,所有编号都出列了, while (p->next!=p) { //找到从p报数1开始,报m的人,并且还要知道数m-1de人的位置tail,方便做删除操作。 for (int i=1; i<m; i++) { tail=p; p=p->next; } tail->next=p->next;//从链表上将p结点摘下来 printf("出列人的编号为:%d\n",p->number); free(p); p=tail->next;//继续使用p指针指向出列编号的下一个编号,游戏继续 } printf("出列人的编号为:%d\n",p->number); free(p); } int main() { printf("输入圆桌上的人数n:"); int n; scanf("%d",&n); person * head=initLink(n); printf("从第k人开始报数(k>1且k<%d):",n); int k; scanf("%d",&k); printf("数到m的人出列:"); int m; scanf("%d",&m); findAndKillK(head,k,m); return 0; }
输出:
输入圆桌上的人数n:5 从第k人开始报数(k>1且k<5):3 数到m的人出列:2 出列人的编号为:4 出列人的编号为:1 出列人的编号为:3 出列人的编号为:2 出列人的编号为:5
希望本文所述对大家C语言程序设计有所帮助。
c语言实现约瑟夫环
一般有循环链表和数组模拟两种方式,貌似还有递归实现的呢!这里主要介绍数组模拟方式。
一. 最简单的约瑟夫环问题
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
如果用数组模拟这个过程,就要考虑两个问题:
1.怎样实现尾部和头部的无缝连接这个循环过程?
意思就是当第n个人报完数时,下一个报数的应该又是1而不是n+1。如果用循环链表确实好做,但用数组的话可以通过while+for来实现,来看看。
while(1){
for(int i=1;i<=n;i++)
cout<<i<<" ";
}
这段程序可以不断地输出1到n的所有值,这不就完成了尾部和头部的无缝连接嘛,我们只需将条件改改就行了。
2.怎么模拟数到m这个过程?
开始时把所有的值状态标记为1,代表这个人在循环的队列中。我们可以不断地遍历这n个值,每当遇到在队列中的人时,计数器num++(这个计数器num只在遇到status[i]==1时自增),当num==m时,这个人出列,计数器清0,状态标记为0(代表这个人出列了,不在循环的队列中),同时用来记录出列人数的count++。当count==n时,n个人已经全部出列,可以退出for和while了。
代码如下:
#include<bits/stdc++.h>
const int maxn = 1111;
using namespace std;
int main(){
int n,m;
int status[maxn];
int count = 0;
int num = 0;
cin>>n>>m;
memset(status,0,sizeof(status));
for(int i=1;i<=n;i++)
status[i] = 1;
while(count<n){
for(int i=1;i<=n;i++){
if(status[i] == 1)
num++;
if(num == m){
cout<<i<<" ";
status[i] = 0;
count++;
num = 0;
}
if(count == n)
break;
}
}
return 0;
}
二. 简单的约瑟夫环问题
这个问题和上面的一样,不过这里的问题变成了每个人有一个可以输入的编号,而不再是1~n这样编号了。其实本质和上面是一样的,无非是加一个sum[ ]数组记录这n个人的编号罢了,输出的时候不再输出i了,而是输出i对应的编号sum[ i ]。
直接瞧代码吧:
#include<bits/stdc++.h>
const int maxn = 1111;
using namespace std;
int main(){
int n,m;
int status[maxn];
int sum[maxn];
int count = 0;
int num = 0;
cin>>n>>m;
memset(status,0,sizeof(status));
for(int i=1;i<=n;i++)
cin>>sum[i];
for(int i=1;i<=n;i++)
status[i] = 1;
while(count<n){
for(int i=1;i<=n;i++){
if(status[i] == 1)
num++;
if(num == m){
cout<<sum[i]<<" ";
status[i] = 0;
count++;
num = 0;
}
if(count == n)
break;
}
}
return 0;
}
三.稍稍复杂一丢丢的约瑟夫环问题
这个问题又比上面问题多了一个条件,从第k个人开始报数而不是从1开始报数。那么完整问题是:已知n个人(这n个人的编号可以自己输入)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
实现这个只需要在第二个问题的基础上加上一个flag就行了,具体的窍门自己看,直接上代码:
#include<bits/stdc++.h>
const int maxn = 1111;
using namespace std;
int main(){
int n,m,k;
int status[maxn];
int sum[maxn];
int count = 0;
int num = 0;
int flag = 0;
cin>>n>>m>>k;
memset(status,0,sizeof(status));
for(int i=1;i<=n;i++)
cin>>sum[i];
for(int i=1;i<=n;i++)
status[i] = 1;
while(count<n){
for(int i=1;i<=n;i++){
if(i == k)
flag=1;
if(flag==0)
continue;
if(status[i] == 1)
num++;
if(num == m){
cout<<sum[i]<<" ";
status[i] = 0;
count++;
num = 0;
}
if(count == n)
break;
}
}
return 0;
}
今天的关于PHP实现约瑟夫环问题的方法分析和约瑟夫环 php的分享已经结束,谢谢您的关注,如果想了解更多关于C#实现约瑟夫环、c++约瑟夫环问题、C语言基于循环链表解决约瑟夫环问题的方法示例、c语言实现约瑟夫环的相关知识,请在本站进行查询。
本文标签: