js的循环,感觉有点难

有编号1-90号的90个小朋友,围成一个圈 从1号开始报数,1234567循环报数,喊到7的小朋友退出游戏,最后剩下的6个小朋友的编号(例1234567,7号退出,1234567,14号退出。。。),哪位大神帮忙写下,

阅读 4k
5 个回答

代码是写出来,思想也写出来了,不过貌似不是很好懂,自己用小数据来算一下应该能明白吧。90 个人算出来答案是 [ 15, 48, 53, 64, 73, 85 ],不知道对不对。

const count = 90;
// 产生一个指定长度的数组,编号即序号 + 1
let data = Array.apply(null, { length: count }).map((v, i) => i + 1);

// 第 7 个退出,相当于位置(索引 + 1)除以 7 余数为 0 的时候退出
// 上次数到最后会有 lastRest 个人不够 7 个
// 第一次相当于 lastRest 为 0,即上次刚好数完,最后一个退出的情况
let lastRest = 0;
while (data.length > 6) {
    // 计算应该退出时的余数,因为上次剩下 lastRest 个人(last < 7)
    // 所以要从开始再数 7 - lastRest 个,即位置是 7 - lastRest。
    // 又因为索引是从 0 开始,位置从 1 开始,所以通过位置计算索引需要 -1,
    // 所以计算索引是 (位置 - 1),有可能为负,取正就是 (位置 - 1 + 7) % 7
    // 代入位置算法就是 (7 - lastRest - 1 + 7) % 7,即 (7 - lastRest + 6) % 7
    const special = (7 - lastRest + 6) % 7;

    // 根据这次一共的人数,算会剩下多少个人不够 7 人组
    // 由于有上次剩下的,所以要加进来一起算
    lastRest = (data.length + lastRest) % 7;

    // 把索引 i,除以7 余 special 的过滤掉,相当于留下 != special 的
    data = data.filter((v, i) => i % 7 != special);
}

console.log(data);
var ss = [];
//学生编号
for(var i=1;i<=90;i++){
    ss.push(i);
}

for(var i=1;i<=ss.length,ss.length>6;){
    if(i%7==0){
        ss.splice(i-7,7);//不为7的已经加到数组后面,已报数的可以全部删除
        i=1;//重置i
    }else{
        ss.push(ss[i-1]);//留下来的学生加到数组后面去
        i++;
    }
}

console.log(ss);

判断当前队列的位置是不是到了第七个,是的话就退出当前循环重新从"1"开始,同时还要把第七个从队列中移除,这样子一直循环下去,当队列的长度只剩下6个的时候就退出整个循环

这个有点像是约瑟夫斯问题
我用数组写了下,不过感觉用链表最好

function array_num(aa,y){
    var num=1;
    while(aa.length>6){
        for(i=0;i<aa.length;i++){
            if(num==y){aa[i]=0;num=1;}else{num++}
        }
        var bb=aa.filter(function(x){if(x){return true}else{return false}})
        aa=bb;
    }
    console.log(aa)
}
array_num(arr,7)//这里的arr是1-90的数组

哈,我试着写一个以array list为基础,空间复杂度比较小(不用重新生成list)但时间复杂度稍大的,逻辑容易懂的。要想空间复杂度和时间复杂度都比较小,最好用 linked list。

"use strict"

function filter(q, order) {
    // 本次循环之后留下来的人数
    let stayCount = 0

    q.forEach((e, i) => {
        if (e != null) {
            order ++
            // 当序数满7,重新开始数
            if (order === 7) {
                // 赋值为null,即退出下一轮游戏
                q[i] = null
                order = 0
            } else {
                // 序数不是7的倍数,留下
                stayCount ++
            }
        }
    })
    return {
        order, // 本次循环之后最后一个人的序号, 如第一次的90 = 84 + 6 = (7*12) + 6,序号是:6
        stayCount
    }
}

// 初始化一个 1 - 90 的数组
var queue = new Array(90).fill(0).map((e,i) => i+1)
var stay = queue.length
var order = 0

while(stay >= 7) {
    let r = filter(queue, order)
    stay = r.stayCount
    order = r.order
}

console.log(queue.filter((e, i) => e !== null))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题