资讯专栏INFORMATION COLUMN

记一次JavaScript API练习题

scq000 / 423人阅读

摘要:当我完成这个题目并且看到其他大神的答案时,我就觉得我真的很有必要记录一下这道题,并且思考它在中的实现。表示被查找的值方法返回一个由替换值替换一些或所有匹配的模式后的新字符串。举一反三,多多思考,多多实践才是学习前端的最佳实践。

之前,我在Codewars上看到一道名为Recover a secret string from random triplets的题,这道题使我沉思了很久,最终在朋友的帮助下我完成了这个题目。当我完成这个题目并且看到其他大神的答案时, 我就觉得我真的很有必要记录一下这道题,并且思考它在JavaScript中的实现。

这道题目的大概意思是讲:有一个密码字符串存在,而你会获得这个密码字符串的随机三个字符的集合,根据这个集合你需要还原出这个密码字符串。
已知:
1.密码字符串中不会出现重复的字母
2.这个集合包含了足可以推断出密码字符串的信息
3.密码字符串不会不包含集合中的字母

英文好的朋友可以看下面的原文题干,题目作者解释的比我清楚:

There is a secret string which is unknown to you. Given a collection
of random triplets from the string, recover the original string.

A triplet here is defined as a sequence of three letters such that each letter occurs somewhere before the next in the given string.

"whi" is a triplet for the string "whatisup".

As a simplification, you may assume that no letter occurs more than once in the secret string.
You can assume nothing about the triplets given to you other than that they are valid triplets and that they contain sufficient

information to deduce the original string. In particular, this means
that the secret string will never contain letters that do not occur in
one of the triplets given to you.

也可以通过一个例子来理解题目:

secret1 = "whatisup"    // 密码字符串-->程序的输出
triplets1 = [           // 集合 --> 程序的输入
  ["t","u","p"],
  ["w","h","i"],
  ["t","s","u"],
  ["a","t","s"],
  ["h","a","p"],
  ["t","i","s"],
  ["w","h","s"]
]
var recoverSecret = function(triplets) {
// ... -->程序的实现
}

我认为这道题目做起来很舒服,虽然答案并不是第一时间很快就写出来的,但是题干清楚简单就免除了阅读理解的烦扰也是杜绝了由于题意冗长 理解不到位造成了程序错误。而且实现方法也多种多样,在做完答案后看看大神的最佳实践也是一种享受。

下面是我的解决方案:
首先,列出集合中所有的字母,因为集合和密码字符串中的字母种类是一致且无重复的,所以只需要把列出的所有字母去重就可以得到密码字符串的无序排列。

triplets1 = [           // 原集合
  ["t","u","p"],
  ["w","h","i"],
  ["t","s","u"],
  ["a","t","s"],
  ["h","a","p"],
  ["t","i","s"],
  ["w","h","s"]
]

triplets2 =["t","u","p",  // 列出的所有集合字母
"w","h","i","t","s","u",
"a","t","s","h","a","p",
"t","i","s","w","h","s"]

triplets3 =["t","u","p","w","h","i","s","a"]  // 去重后的集合 无序字符串

然后我们再根据原集合给出的排列规则将无序字符串进行排列,而通过观察,我发现原集合中每个小数组之间的顺序关系太过繁杂甚至有的小数组之间都没有顺序关系(比如 triplets1[0] 和 triplets1[1] ),那么最方便实现的解决办法就是只顾及每个小数组三个字母之间的顺序关系:

["t","u","p"] // 粗体--> 第一个小数组的第一个顺序关系
["t","u","p","w","h","i","s","a"] // 找到 "t" 和 "u" 发现顺序正确
["t","u","p"] // 粗体--> 第一个小数组的第二个顺序关系
["t","u","p","w","h","i","s","a"] // 找到 "u" 和 "p" 发现顺序正确
["w","h","i"] // 粗体--> 第二个小数组的第一个顺序关系
["t","u","p","w","h","i","s","a"] // 找到 "w" 和 "h" 发现顺序正确
["w","h","i"] // 粗体--> 第二个小数组的第二个顺序关系
["t","u","p","w","h","i","s","a"] // 找到 "h" 和 "i" 发现顺序正确
["t","s","u"] //粗体--> 第三个小数组的第一个顺序关系
["t","u","p","w","h","i","s","a"] // 找到 "t" 和 "s" 发现顺序不正确
["s","u","p","w","h","i","t","a"] // 交换位置
// ...依次类推,最后的结果是
["w","t","a","h","p","i","u","s"]

很明显可以看到只根据一次的比较还不足以得到结果的顺序,所以我们要外套一个循环,继续使用原集合的顺序信息继续排序,直到全部排序完成输出答案。

下面是我JavaScript的程序实现:

const recoverSecret =(triplets)=> {
let result = ""
//  排列集合字符串 去重
  for(let i=0; i < triplets.length; i++){      
    for(let j = 0; j < triplets[i].length; j++){
      if (result.indexOf(triplets[i][j]) == -1){
        result += triplets[i][j]
      }
    }
  }
 // 用于标识while大循环是否进行
  var flag = true
  while(flag){
  flag = false
   for(let i = 0; i < triplets.length; i++){
     for(let j = 0; j < 2; j++){
       if (result.indexOf(triplets[i][j]) > result.indexOf(triplets[i][j+1])){
         flag = true
// 给交换字母位置
         result = result.replace(triplets[i][j], triplets[i][j+1]).replace(triplets[i][j+1], triplets[i][j])
       }
     }
   }
   }
  return result
}

代码中用到的API比较少,差不多为以下两个:

String.indexOf(searchValue)
方法返回调用String对象中第一次出现的指定值的索引,开始在 fromIndex进行搜索。
searchValue表示被查找的值

String.replace(regexp, substr)
方法返回一个由替换值替换一些或所有匹配的模式后的新字符串。模式可以是一个字符串或者一个正则表达式, 替换值可以是一个字符串或者一个每次匹配都要调用的函数。
regexp表示要被替换的字符串
substr表示替换的字符串

*以上API资料来源于MDN

最后我要说 这个题目还远远没有完,而它的迷人之处就在于它不止一个解决办法,如果你没有思路,可以在Codewars上粘贴我上面的代码并提交(这样你才可以看到别人的答案)研究大神的解决方案就会发现它的魅力。举一反三,多多思考,多多实践才是学习前端的最佳实践。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107657.html

相关文章

  • 一次重装nginx时遇到的问题

    摘要:起因之前在网上看文章提到说,通过的方式安装,可能安装不是最新版本的情况,考虑到在下第一次安装,以后肯定会有卸载重新安装新版本的需求,刚好刚开始学习,索性练习下卸载重装的过程。 起因 之前在网上看文章提到说,通过apt-get的方式安装nginx,可能安装不是最新版本的情况,考虑到在Ubuntu下第一次安装nginx,以后肯定会有卸载重新安装新版本的需求,刚好刚开始学习nginx,索性练...

    Vultr 评论0 收藏0
  • 一次小程序开发中如何使用async-await并封装公共异步请求

    摘要:实现方案首先小程序目前还是不支持的和的,那么如何让它支持呢点击下载,并把下载好的文件夹放到自己小程序的目录下,包总共才多,体积很小的。如果想使用这些新的对象和方法,必须使用,为当前环境提供一个垫片。用于实现浏览器并不支持的原生的代码。 前言 在平常的项目开发中肯定会遇到同步异步执行的问题,还有的就是当执行某一个操作依赖上一个执行所返回的结果,那么这个时候你会如何解决这个问题呢; 1.是...

    why_rookie 评论0 收藏0
  • 一次惊心动魄的前端性能优化之旅

    摘要:方案未引起重视,并没有做出相应处理。页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。这里可以使用的和来分析的性能。写在最后性能优化是一门做减法的艺术。 欢迎一起交流 欢迎关注我的个人公众号,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文从这里开始...

    Bryan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<