The challenge description is as follows:
You are given an array
strarr
of strings and an integerk
. Your task is to return the first longest string consisting ofk
consecutive strings taken in the array.Example:
longest_consec(["zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"], 2) --> "abigailtheta"
n
being the length of the string array, ifn = 0
ork > n
ork <= 0
return""
.
I solved the challenge with as a side goal to follow and use ECMAScript 6 as much as possible. All suggestions on improving the code are welcome!
Note: I did not like using k
and n
in code, so I used numStr
and arrLen
respectively.
const longestConsec = (strArr, numStr) => {
const arrLen = strArr.length
if (arrLen === 0 || numStr > arrLen || numStr <= 0) {
return ""
}
const consecStrings = getAllConsecutiveStrings(strArr, numStr, arrLen)
return getFirstLongestString(consecStrings)
}
const getAllConsecutiveStrings = (strArr, numStr, arrLen) => {
const numConsecStr = arrLen - numStr
const result = []
let consecStr
for (let i = 0; i <= numConsecStr; i++) {
consecStr = ""
for (let s = i; s < i + numStr; s++) {
consecStr += strArr[s]
}
result.push(consecStr)
}
return result
}
const getFirstLongestString = strArr => {
let firstlongestString = ""
let longestLength = 0
for (let str of strArr) {
strLen = str.length
if (strLen > longestLength) {
firstlongestString = str
longestLength = strLen
}
}
return firstlongestString
}
1 Answer 1
Some performance-related nitpicking:
- Instead of string concatenation keep an array of string lengths;
- Use a running window of current concatenated length: when advancing to the next string simply subtract the first window's element and add the current string length.
Thus the array will be iterated just once, no extra strings interned in the JS engine.
const longestConsec = (strings, count) => {
let n = strings.length;
if (!n || count <= 0 || count > strings.length)
return '';
let lengths = Array(n);
// fill the running window
let windowLen = 0;
for (let i = 0; i < count - 1; i++) {
let stringLen = strings[i].length;
windowLen += stringLen;
// fill the cache with items 0..count-1, the rest will be filled in the main loop
lengths[i] = stringLen;
}
let maxLen = 0;
let maxLenAt = 0;
for (let i = count - 1, windowStart = 0; i < n; i++, windowStart++) {
let stringLen = strings[i].length;
lengths[i] = stringLen;
let thisLen = windowLen + stringLen;
if (thisLen > maxLen) {
maxLen = thisLen;
maxLenAt = windowStart;
}
windowLen += stringLen - lengths[windowStart];
}
return strings.slice(maxLenAt, maxLenAt + count).join('');
}
-
\$\begingroup\$ You don't actually need the first
for
loop, you can leavewindowLen
set to0
, the main loop will take care of the rest. \$\endgroup\$ChatterOne– ChatterOne2017年02月13日 16:40:04 +00:00Commented Feb 13, 2017 at 16:40 -
\$\begingroup\$ Did you actually try it? See this fiddle: jsfiddle.net/mp4xkgd5 \$\endgroup\$ChatterOne– ChatterOne2017年02月14日 07:37:46 +00:00Commented Feb 14, 2017 at 7:37
-
1\$\begingroup\$ Your code returns incorrect result
zoneabigail
for count=2. \$\endgroup\$woxxom– woxxom2017年02月14日 07:41:37 +00:00Commented Feb 14, 2017 at 7:41
Explore related questions
See similar questions with these tags.