Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript中高效计算Josephus置换_Javascript_Arrays_Algorithm_Permutation_Josephus - Fatal编程技术网

Javascript中高效计算Josephus置换

Javascript中高效计算Josephus置换,javascript,arrays,algorithm,permutation,josephus,Javascript,Arrays,Algorithm,Permutation,Josephus,在进行代码战培训时,我遇到了一个关于约瑟夫排列的挑战,我尝试先在纸上解决它,然后再将它翻译成代码 问题如下: 创建一个返回Josephus置换的函数,将要置换的项目的初始数组/列表作为参数,就像它们在一个圆圈中一样,并每隔k个位置计数,直到没有剩余的位置 我的主要想法是: 有一个辅助数组来保持响应 使用两个迭代器: i:跟踪给定数组中的当前索引 k:跟踪排列的步骤 在0处初始化i,在1处初始化k 当原始数组只剩下一个元素时: 将元素推送到输出数组 当i不是数组的最后一个索引时: 如果

在进行代码战培训时,我遇到了一个关于约瑟夫排列的挑战,我尝试先在纸上解决它,然后再将它翻译成代码

问题如下: 创建一个返回Josephus置换的函数,将要置换的项目的初始数组/列表作为参数,就像它们在一个圆圈中一样,并每隔k个位置计数,直到没有剩余的位置

我的主要想法是:

  • 有一个辅助数组来保持响应
  • 使用两个迭代器:

    • i:跟踪给定数组中的当前索引
    • k:跟踪排列的步骤
  • 在0处初始化i,在1处初始化k

  • 当原始数组只剩下一个元素时:
    • 将元素推送到输出数组
  • 当i不是数组的最后一个索引时:
    • 如果k=步骤:
      • 从原始数组中取出元素,将其推入输出数组,最后替换k=1
    • 如果k!=步骤:
      • 增量i和k
  • 当i是原始数组的最后一个索引(且该数组有多个元素)时:
    • 如果k=步骤:
      • 从原始数组中取出元素,将其推入输出数组,替换k=1并设置i=0
    • 如果k!=步骤:
      • 设置i=0并增加k
我的问题是,我怎样才能使这更有效

我使用的算法是错误的还是实现的

一篇评论提到了两件事:

  • push()非常慢,这是我的一种可能性(错误的数据结构)

  • 建议看递归(这让我更加怀疑算法)。不过,我并没有真正了解如何使其递归


提前感谢您的帮助

您是否尝试过实施功能性方法? 发件人:

函数getSafePosition(n){
//求方程的L值
值OFL=n-高值(n);
安全位置=2*L+1的值;
返回安全位置;
}
函数highestOneBit(i){
i |=(i>>1);
i |=(i>>2);
i |=(i>>4);
i |=(i>>8);
i |=(i>>16);
返回i-(i>>1);
}

这应该在O(n)

中运行,有一个循环,可以将其记录下来。(这似乎通过了Codewars测试。)

函数g(n,k,i,memo){
if(memo.hasOwnProperty([n,k,i]))
返回备忘录[[n,k,i]];
如果(i==1)
返回备忘录[[n,k,i]]=(k-1)%n;
返回备忘录[[n,k,i]]=
(k+g(n-1,k,i-1,memo))%n;
}
函数f(A,k){
设n=A.长度;
设结果=新数组(n);
让memo={};

对于(设i=1;i),可以将前导位移到末尾

constjosephus=(x)=>parseInt(x.toString(2).substr(1)+1,2);

我不知道codereview,我会检查它。我正在寻找替代方案,但在递归方面没有任何想法。
拼接
往往很昂贵,但我无法想象你提供的测试可以持续12秒,除非你的代码中的一些循环被卡住或在大量重复之后设置为完成@如果我没记错的话,CodeWars给了你一些示例测试用例,这样你就可以测试你的算法的正确性,但是隐藏了它用来确保运行效率的其他测试用例。我可能计算出了我的大O错误,但我的代码不应该围绕O(步骤*n)=O(n)运行吗?将检查该解决方案!OP将
步骤
作为参数,它并不总是
2
。您能帮我解决这个约瑟夫斯问题的变体吗:-->谢谢:-)
function josephus(items,step){
  var output = [];
  var i = 0;
  var k = 1;
  if( items == [] ) {
    return [];
  }
  while (items.length != 1) {
    if        (k == step && i == items.length - 1) {
      output.push(items[i]); 
      items.splice(i, 1);
      i = 0;
      k = 1;
    } else if (k == step && i != items.length - 1) {
      output.push(items[i]);
      items.splice(i, 1);
      k = 1
    } else if (k < step && i == items.length - 1) {
      k++;
      i=0;
    } else if (k < step && i != items.length - 1) {
      k++;
      i++;
    }
  }
  output.push(items[0]);
  return output;
}
Test.assertSimilar(josephus([1,2,3,4,5,6,7,8,9,10],1),[1,2,3,4,5,6,7,8,9,10])
Test.assertSimilar(josephus([1,2,3,4,5,6,7,8,9,10],2),[2, 4, 6, 8, 10, 3, 7, 1, 9, 5])
Test.assertSimilar(josephus(["C","o","d","e","W","a","r","s"],4),['e', 's', 'W', 'o', 'C', 'd', 'r', 'a'])
Test.assertSimilar(josephus([1,2,3,4,5,6,7],3),[3, 6, 2, 7, 5, 1, 4])
Test.assertSimilar(josephus([],3),[])