1

I'm defining a Python function to determine the longest string if the original strings are combined for every k consecutive strings. The function takes two parameters, strarr and k.

Here is an example:

max_consec(["zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"], 2) --> "abigailtheta"

Here's my code so far (instinct is that I'm not passing k correctly within the function)

def max_consec(strarr, k):
    lenList = []
    for value in zip(strarr, strarr[k:]):
        consecStrings = ''.join(value)
        lenList.append(consecStrings)
    for word in lenList: 
        if max(word):
            return word

Here is a test case not passing:

testing(longest_consec(["zone", "abigail", "theta", "form", "libe", "zas"], 2), "abigailtheta")

My output:

'zonetheta' should equal 'abigailtheta'
Mr. Jibz
  • 511
  • 2
  • 7
  • 21
  • What problem you're facing? – geckos Mar 23 '19 at 19:28
  • see revised test case and outputs above – Mr. Jibz Mar 23 '19 at 19:33
  • 1
    Among other problems, `if max(word)` doesn't test whether that word is the longest word in `lenList`. It iterates over the characters of `word` and finds the one with the highest Unicode code point, then tests the truth value of that character (which is always true, because the truth value of a string is determined by whether it has any characters in it). – user2357112 Mar 23 '19 at 19:41

4 Answers4

1

It's not quite clear to me what you mean by "every k consecutive strings", but if you mean taking k-length slices of the list and concatenating all the strings in each slice, for example

['a', 'bb', 'ccc', 'dddd']  # k = 3

becomes

['a', 'bb', 'ccc']
['bb', 'ccc', 'dddd']

then

'abbccc'
'bbcccddd'

then this works ...

# for every item in strarr, take the k-length slice from that point and join the resulting strings
strs = [''.join(strarr[i:i + k]) for i in range(len(strarr) - k + 1)]

# find the largest by `len`gth
max(strs, key=len)

this post gives alternatives, though some of them are hard to read/verbose

joel
  • 6,359
  • 2
  • 30
  • 55
  • To make this answer perfect, I would add "-k+1" to the range() argument. Otherwise, you get extraneous elements in the "strs" list of length less than k. – AlexK Mar 23 '19 at 20:09
1
def max_consec(strarr, k):
    n = -1
    result = ""
    for i in range(len(strarr)):
        s = ''.join(strarr[i:i+k])
        if len(s) > n:
            n = len(s)
            result = s     
    return result
  • Iterate over the list of strings and create a new string concatenating it with next k strings
  • Check if the newly created string is the longest. If so memorize it
  • Repeat the above steps until the iterations complete
  • return the memorised string
mujjiga
  • 16,186
  • 2
  • 33
  • 51
1

Store the string lengths in an array. Now assume a window of size k passing through this list. Keep track of the sum in this window and starting point of the window.

When window reaches the end of the array you should have maximum sum and index where the maximum occurs. Construct the result with the elements from this window.

Time complexity: O(size of array + sum of all strings sizes) ~ O(n)

Also add some corner case handling when k > array_size or k <= 0

def max_consec(strarr, k):

    size = len(strarr)

    # corner cases
    if k > size or k <= 0:
        return "None"  # or None

    # store lengths
    lenList = [len(word) for word in strarr]

    print(lenList)

    max_sum = sum(lenList[:k])   # window at index 0
    prev_sum = max_sum
    max_index = 0

    for i in range(1, size - k + 1):
        length = prev_sum - lenList[i-1] + lenList[i + k - 1]  # window sum at i'th index. Subract previous sum and add next sum
        prev_sum = length

        if length > max_sum:
            max_sum = length
            max_index = i

    return "".join(strarr[max_index:max_index+k])  # join strings in the max sum window


word = max_consec(["zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"], 2)

print(word)
HariUserX
  • 1,341
  • 1
  • 9
  • 17
  • It doesn't really take time proportional to the sum of all string lengths, since for most strings, we only check their length. We don't copy them or anything, and in Python, strings store their length, so `len` isn't as expensive as a C `strlen`. – user2357112 Mar 23 '19 at 20:52
  • But it takes time if k is equal to size of array, Then we have to join all strings. I specified the worst case. – HariUserX Mar 23 '19 at 20:53
0

If I understand your question correctly. You have to eliminate duplicate values (in this case with set), sort them by length and concatenate the k longest words.

>>> def max_consec(words, k):
...   words = sorted(set(words), key=len, reverse=True)
...   return ''.join(words[:k])
...
>>> max_consec(["zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"], 2)
'abigailtheta'

Update: If the k elements should be consecutive. You can create pairs of consecutive words (in this case with zip). And return the longest if they get joined.

>>> def max_consec(words, k):
...     return max((''.join(pair) for pair in zip(*[words[i:] for i in range(k)])), key=len)
...
>>> max_consec(["zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"], 2)
'abigailtheta'
Querenker
  • 2,242
  • 1
  • 18
  • 29
  • I'm pretty sure that's not it. It looks like the task is to find the longest string that can be produced by concatenation `k` consecutive elements of `words`. It doesn't matter whether elements happen to be duplicates, and you aren't allowed to reorder the elements the way you're doing. – user2357112 Mar 23 '19 at 19:37
  • For example, if the input was `['a', 'bcde', 'fg', 'hij']`, the output would be `'bcdefg'`, not `'bcdehij'`. – user2357112 Mar 23 '19 at 19:38
  • @user2357112 I checked your "test case" and it now correctly returns 'bcdefg' – Querenker Mar 23 '19 at 19:58