嗨~我是 A Fei,又到了我们愉快的解题时间,让我们马上来看看今天的题目:
(题目来源:Codewars)
You are given an array(list) strarr of strings and an integer k. Your task is to return the first longest string consisting of k consecutive strings taken in the array.
Examples:
strarr = ["tree", "foling", "trashy", "blue", "abcdef", "uvwxyz"], k = 2
Concatenate the consecutive strings of strarr by 2, we get:
treefoling (length 10) concatenation of strarr[0] and strarr[1]
folingtrashy (" 12) concatenation of strarr[1] and strarr[2]
trashyblue (" 10) concatenation of strarr[2] and strarr[3]
blueabcdef (" 10) concatenation of strarr[3] and strarr[4]
abcdefuvwxyz (" 12) concatenation of strarr[4] and strarr[5]
Two strings are the longest: "folingtrashy" and "abcdefuvwxyz".
The first that came is "folingtrashy" so
longest_consec(strarr, 2) should return "folingtrashy".
In the same way:
longest_consec(["zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"], 2) --> "abigailtheta"
n being the length of the string array, if n = 0 or k > n or k <= 0 return "".
Note
consecutive strings : follow one after another without an interruption
题目要我们将一个含有 n 个字串元素的阵列,依序以 k 个组成後,比较哪个字串比较长。如果一样长,就回传第一个值 ,此点非常重要,我当时看漏这个条件所以卡关超久...先贴我的答案:
def longest_consec(strarr, k)
if strarr.length == 0 || k <= 0 || k > strarr.length
""
else
arr = []
i = 0
while i < (strarr.length - k) + 1
arr[i] = strarr.slice(i, k).join("")
i += 1
end
arr.reduce { |memo, word| memo.length >= word.length ? memo : word }
end
end
题目很「贴心」地帮我们写出了例外条件「n being the length of the string array, if n = 0 or k > n or k <= 0 return ""」,我知道这样写很丑,但是为了赶时间直接在 if 判断中写死,好让我专心破解核心部分。
试着在脑海中模拟一下,假设有阵列 [1, 2, 3, 4],要依序取出 [1, 2]、[2, 3]、[3, 4],总共是要重复做三次事,也就是要跑 3 次回圈,所以「跑几圈」就是阵列长度 n 减去取出的元素个数 k,别忘了还要 + 1,写成 while 回圈就是:
while i < (strarr.length - k) + 1
#do something
i += 1
end
接下来用 slice 方法,可以从原阵列中「切出」一部份,第一个参数是 index,第二个则是你要切的「长度」,这里就可以从 strarr[0] 开始,切出 k 长度的阵列,再用 join 组成字串,塞进空阵列 arr 里。
最後,就是用经典的 reduce 方法,两两比较 arr 中哪个字串比较长,「胜者」就留下来挑战下一个,直到最後「存活」下来那一个,就是最长的字串。但是题目有强调,如果碰到一样长的字串,留下来的是先出现的那个,也就是要写成 memo.length >= word.length ? memo : word
而非 memo.length > word.length ? memo : word
,这就是我解题鬼打墙最久的地方。
比较评分最高的解法:
def longest_consec(strarr, k)
return "" unless k.between?(1, strarr.length)
strarr.each_cons(k).map(&:join).max_by(&:length) || ""
end
Wow,第一行就用了我没看过的 between? 方法,不过字面上的意义很好懂,这里就不深入分析了。而下一行也是让人眼花撩乱,有两个没看过的方法,大哥你是把整本手册都背起来了吗?只能先查一下手册:
1.each_cons 方法,带入 a,就可以从 Enumerable 迭代取出长度为 a 的值,简直是为这题量身打造,直接看官网范例:
(1..10).each_cons(3) { |a| p a }
# outputs below
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
如果後面没有接 {} 的话,它会回传一个枚举器 enumerator。
map{|el| el.join("")}
,这部分可以等日後再谈。好啦,这次的解题纪录就先到这,最近比较忙没什麽时间喇赛想梗,希望之後能多一点时间写文,掰掰啦
一. BOW BOW的全名为Bag-of-words,中文是'一袋文字',意思就是将词都丢进一个袋子...
第 34 天:妥善运用 LINE Notify 免费推播 「恩...我是在想你今天晚上要不要用pus...
Classification - Predict category or class Train r...
以微框架来说,i18n 不是必备的功能,但如果是想要开发面向一般大众的服务,在这个国际化的时代,i1...
纪录一下最近遇到的问题 一支异动订单的API ,称作 Patch Order,在一秒内被打了两次,造...