【问题标题】:Longest of k consecutive stringsk个连续字符串中最长的
【发布时间】:2019-08-14 11:56:25
【问题描述】:

我正在定义一个 Python 函数来确定最长的字符串,如果原始字符串针对每 k 个连续字符串进行组合。该函数有两个参数,strarrk

这是一个例子:

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

到目前为止,这是我的代码(本能是我没有在函数中正确传递 k

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

这是一个没有通过的测试用例:

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

我的输出:

'zonetheta' should equal 'abigailtheta'

【问题讨论】:

  • 你遇到了什么问题?
  • 查看上面修改过的测试用例和输出
  • 除其他问题外,if max(word) 不会测试该单词是否是 lenList 中最长的单词。它遍历word的字符并找到具有最高Unicode代码点的字符,然后测试该字符的真值(始终为真,因为字符串的真值取决于它是否有任何字符)它)。

标签: python string function


【解决方案1】:

如果我正确理解您的问题。您必须消除重复值(在本例中为 set),按长度对它们进行排序并连接 k 个最长的单词。

>>> 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'

更新: 如果k个元素应该是连续的。您可以创建成对的连续单词(在本例中为 zip)。如果他们加入,则返回时间最长。

>>> 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'

【讨论】:

  • 我很确定不是这样。看起来任务是找到可以通过连接k 的连续元素words 产生的最长字符串。元素是否碰巧重复并不重要,并且您不能按照您正在做的方式重新排列元素。
  • 例如,如果输入为['a', 'bcde', 'fg', 'hij'],则输出为'bcdefg',而不是'bcdehij'
  • @user2357112 我检查了您的“测试用例”,它现在正确返回了“bcdefg”
【解决方案2】:

我不太清楚你所说的“每 k 个连续的字符串”是什么意思,但是如果你的意思是取列表的 k 长度切片并连接每个切片中的所有字符串,例如

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

变成

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

然后

'abbccc'
'bbcccddd'

那么这行得通...

# 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 提供了替代方案,尽管其中一些难以阅读/冗长

【讨论】:

  • 为了使这个答案完美,我会在 range() 参数中添加“-k+1”。否则,您会在长度小于 k 的“strs”列表中获得无关元素。
【解决方案3】:
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
  • 遍历字符串列表并创建一个新字符串将其与下一个 k 字符串连接
  • 检查新创建的字符串是否最长。如果是,请记住它
  • 重复上述步骤,直到迭代完成
  • 返回记忆的字符串

【讨论】:

    【解决方案4】:

    将字符串长度存储在数组中。现在假设一个大小为 k 的窗口通过这个列表。跟踪此窗口中的总和和窗口的起点。

    当窗口到达数组的末尾时,您应该有最大的总和和出现最大值的索引。使用此窗口中的元素构造结果。

    时间复杂度:O(数组大小+所有字符串大小之和)~O(n)

    k > array_sizek <= 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)
    

    【讨论】:

    • 实际上并不需要与所有字符串长度之和成正比的时间,因为对于大多数字符串,我们只检查它们的长度。我们不复制它们或任何东西,在 Python 中,字符串存储它们的长度,所以 len 不像 C strlen 那样昂贵。
    • 但是如果 k 等于数组的大小需要时间,那么我们必须连接所有字符串。我指定了最坏的情况。
    猜你喜欢
    • 2020-01-19
    • 2017-05-30
    • 1970-01-01
    • 2015-06-08
    • 2020-11-08
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多