如何实现堆栈数据结构以进行范围提取(codewars 任务)?

Posted

技术标签:

【中文标题】如何实现堆栈数据结构以进行范围提取(codewars 任务)?【英文标题】:How to implement stack data structure to range extraction (codewars task)? 【发布时间】:2022-01-05 04:33:07 【问题描述】:

我正在与名为 Range Extraction 的 codewars kata 苦苦挣扎 - 它以递增顺序获取整数列表,并以范围格式返回格式正确的字符串(重叠的单独间隔)。

示例解决方案:

([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]);
// returns "-6,-3-1,3-5,7-11,14,15,17-20"

在我的解决方案中,我没有得到-6,-3-1,3-5,7-11,14,15,17-20,而是得到了最后一项-6,1,5,11,15,20

如何改进我的解决方案?代码:

function solution(list)
    let result=[]
    for(let i=0;i<list.length;i++)
        let e2=list[i]
        let e1 = result[result.length-1]
        if(e2-e1==1)
            result[result.length-1]=e2
        
        else
          result.push(e2 )
        
    
    return result

console.log(solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]))
  

【问题讨论】:

顺便说一句,我必须完全重新格式化您的问题才能理解它在说什么。如果您想得到答案,请尽量使您的问题清晰易读。 请原谅我,我的英语不好,下次我会尽力解决问题,谢谢你的努力 【参考方案1】:

您没有做任何事情来以范围格式写入连续整数。相反,您只是将先前的结果替换为范围内的最终项目,这完全反映在您的解决方案中:

-6: this number has no "neighbors" so is fine
1: the  final item in the first range
5: the final item in the second range
...

问题在于循环的内部逻辑。

总而言之,你需要一段时间而不是 if 并且你需要追加而不是替换:

function solution(list)
    let result=[]

    for(let i=0;i<list.length;i++)
        //write first value in range to result
        result.push(list[i].toString())
        //if this is the last entry, we are done 
        if(i === list.length - 1)
            break
        
        //initialize variables
        let e1 = list[i]
        let e2 = list[i+1]
        let isRange = false
        //run thorugh array while we get consecutive numbers
        while(e2-e1===1 && i < list.length-1)
            //modify the OUTER LOOP index variable.
            //This means when we return to the beginning of hte for loop,
            // we will be at the beginning of the next range
            i++ 
            e1 = list[i]
            e2 = list[i+1]
            isRange = true
        
        //if there were any consecutive numbers
        if(isRange)
            //rewrite the last entry in result as a range
            result[result.length-1]+="-" + list[i].toString()
        
    
    return result.toString()

console.log(solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]))

现在,您的外循环会遍历整个数组一次。内部循环将确保外部循环跳过列表中出现在范围内的任何项目。最后,如果内部循环找到任何范围,它会将条目重写为正确的范围。

【讨论】:

非常感谢,天哪,我觉得我的尝试完全不同,我真的觉得我迷路了 @medazzouzi 我试图让代码尽可能与您的相似,但是鉴于问题的性质,不可能保持完全相同。你在哪里迷路了? 非常感谢我非常喜欢你的代码我有点不明白为什么你在 while 循环中重新分配 e1 和 e2 变量以及这个语句 if(i === list.length - 1 ) break 有必要保留吗? 老实说不确定 - 我不是 javascript 专家。如果您不保留它,那么如果最后一项不是范围,那么您将最终设置let e2 = list[i+1],它超出了数组的末尾。在大多数语言中,这会导致异常,但 javascript 可能会使其未定义。无论如何,明确一点似乎更好 - 如果我们在最后一项,甚至不检查范围。我确实尝试在没有检查的情况下运行它,它似乎工作正常,所以请随意删除。另外,如果我的回答令人满意,请接受并给我一个支持:) 关于e1e2的重新赋值——需要检查列表中的下一个元素是否在范围内,所以需要重新赋值一次e1e2 i 已增加。从技术上讲,如果您在 while 循环条件中显式使用列表,则根本不需要 e1e2while(list[i+1]-list[i]===1 &amp;&amp; i &lt; list.length-1) 但我想尽可能地模仿您的代码。

以上是关于如何实现堆栈数据结构以进行范围提取(codewars 任务)?的主要内容,如果未能解决你的问题,请参考以下文章

如何提取学习的 ML 模型以实现不同的实现?

如何进行查询以仅获取在值范围内具有 N 个数字的结果?

如何提取位于Sql中的范围内的数据

如何从 c 代码中提取所有库函数的堆栈大小?

Codewar

MATLAB 实现点云累计-坐标系转换-目标范围点云提取(附代码与代码注释)