GVKun编程网logo

PHP实现约瑟夫环问题的方法分析(约瑟夫环 php)

14

在本文中,我们将详细介绍PHP实现约瑟夫环问题的方法分析的各个方面,并为您提供关于约瑟夫环php的相关解答,同时,我们也将为您带来关于C#实现约瑟夫环、c++约瑟夫环问题、C语言基于循环链表解决约瑟夫

在本文中,我们将详细介绍PHP实现约瑟夫环问题的方法分析的各个方面,并为您提供关于约瑟夫环 php的相关解答,同时,我们也将为您带来关于C#实现约瑟夫环、c++约瑟夫环问题、C语言基于循环链表解决约瑟夫环问题的方法示例、c语言实现约瑟夫环的有用知识。

本文目录一览:

PHP实现约瑟夫环问题的方法分析(约瑟夫环 php)

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#实现约瑟夫环

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++约瑟夫环问题

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语言基于循环链表解决约瑟夫环问题的方法示例

本文实例讲述了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语言实现约瑟夫环

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语言实现约瑟夫环的相关知识,请在本站进行查询。

本文标签: