约瑟夫环算法

 前段时间在逛百度的时候,发现了约瑟夫环这个算法;当时刚好忙完了,左右没事就花了点时间去研究了下这个算法,研究了才知道这算法还真点研究价值。
      话说,在犹大人和罗马的战争期间,约瑟夫和其他40个犹大人反判者被罗马军队困在一个山洞中;这些犹大人反判者宁愿自己自杀也不想成为罗马的俘虏,于是他们站成了一个圆,从其中的某个人开始数每数到三就要被杀掉,直到所有人死光。但约瑟夫和他的一个朋友觉得自杀没意义,并不想死,于是他们很快就算出他和他朋友应该站在什么位置,使他们成为最后两个人,并最终活下来。
     从上面的事件中我们可以知道两点信息:
     1、人员的总数:40;
     2、每次数到三的人都要被杀掉(数到数值):3;     好,现在我们就来解决这一题,然后写出成一个算法:
     首先,我们先把每个人分配个编号,第一个数数的为1号,第二个为2号,以些类推一直到40号;然后我们可以慢慢排除要死掉的人,剩下的最后两位数就是我们最终的解(13,28)。
    方法操作思路出来了,我们就可以对算法进行实现了,代码如下:

 1 /// <param name="strArr">源数组(1-40)</param>
 2        /// <param name="Num">数到几移除(3)</param> 
 3        /// <param name="StartNum">开始数(1)</param>
 4        /// <returns></returns>
 5        public ArrayList GetArrList(ArrayList strArr, int Num, int StartNum)
 6        {
 7  
 8            ArrayList ArrSource = new ArrayList();
 9            int nCount = 1; 
10            int index = StartNum - 1;
11            while (strArr.Count > 0)
12            {
13                //数到移除数(3)
14                if (nCount == Num)
15                {
16                    ArrSource.Add(strArr[index]);
17                    strArr.Remove(strArr[index]);
18                    nCount = 1;
19                }
20                else
21                { 
22                    nCount++;
23                    index++;
24                }
25                //数到最后一个后回到每一个。
26                if (index == strArr.Count)
27                {
28                    index = 0;
29                }
30            }
31            return ArrSource;
32        }

注:因在发现此算法时是在博客园 https://www.cnblogs.com/bg1qqc/p/8261837.html 发现的,所以算法中的代码会有所相似,固本人多写了别一种实现方式代码如下:

 1         /// <param name="strArr">源数组</param>
 2         /// <param name="Num">到几出移除</param>
 3         /// <param name="StartNum">开始值</param>
 4         /// <param name="nNumder"></param>
 5         /// <returns>返回算法中的最后两位</returns>
 6         public static ArrayList GetArrList(ArrayList strArr, int Num, int StartNum, int nNumder = 1)
 7         {
 8             int nCount = strArr.Count;
 9             if (nCount == 2)
10             {
11                 return strArr;
12             }
13             int index = 0;
14             for (int i = StartNum; i <= nCount; i++)
15             {
16                 if (nNumder == Num)
17                 {
18                     //如要输出出列顺序数组,只需声明数组把移除的值依次增加到新声明数组中方可。
19                     strArr.RemoveAt(index);
20                     nNumder = 1;
21                 }
22                 else
23                 {
24                     index++;
25                     nNumder++;
26                 }
27             }
28             return GetArrList(strArr, Num, StartNum, nNumder);
29         }


如有不足或写错的地方欢迎指正,谢谢!!!!


  

原文地址:https://www.cnblogs.com/ljhboke/p/8397559.html