试图解决最长子字符串的变体,但卡在while循环中[关闭]

Trying to solve a variant of longest substring, but getting stuck in a while loop [closed]

提问人:Aboullkhill 提问时间:11/16/2023 最后编辑:phoAboullkhill 更新时间:11/16/2023 访问量:89

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将帮助其他人回答这个问题。

4天前关闭。

因此,我一直在尝试解决一个练习问题,其中给定一个字符串,返回该字符串中出现的最长的唯一子字符串。例如,如果字符串是“aab”,则我的函数的输出应该是“ab”。

以下是我尝试的解决方案,当我运行它时,函数永远不会结束,所以我一步一步地查看它,并注意到我的函数永远不会超过第一个 while 循环,但我不确定为什么。在此处输入图像描述

python 子字符串

评论

0赞 Hugh Granger 11/16/2023
你是说唯一字符的 longes 子字符串吗?
1赞 leaf_yakitori 11/16/2023
你应该发布你的代码,这样我们就可以复制它来找到错误,而不是截图。
0赞 Nikolaj Š. 11/16/2023
代码图像

答:

2赞 SuNing 11/16/2023 #1

您的问题是关于子字符串而不重复吗?我尝试了你的代码,它卡住了,因为data.get(s[j], -1)一直是0,所以你的j一直是1并卡在循环中。您可以调试它并更改查找重复字符的方式。这里有一个代码可能会给你一些帮助。

def LongestSubstring(s: str):
i = 0
if len(s) == 0:
    return None
while i < len(s):
    sub_size = len(s) - i
    start = 0
    while start < (len(s) - sub_size + 1):
        sub = s[start:(start + sub_size)]
        start = start + 1
        for k in sub:
            counts = sub.count(k)
            if counts > 1:
                break
            if k == sub[len(sub) - 2]:
                return sub
    i = i + 1
1赞 NoDakker 11/16/2023 #2

在花一些时间重新键入代码然后对其进行测试时,我尝试调试代码中的各个点,但我似乎一直在兜圈子,试图查看函数未正确检查最长子字符串的位置。因此,为了提供另一种思路,以下是该函数的重构版本以及用于验证新思路的测试字符串。

在这些类型的练习中,通常需要做的是尝试找到最长的唯一字符字符串,从字符串的第一个位置开始,然后从字符串的第二个位置重新进行测试,然后是第三个位置,依此类推,直到到达最后一个字符位置。同时,在每次传递时对最长的唯一字符串进行检查,并检查并保存找到的最长子字符串。因此,以下是代码的重构版本,作为思考的食粮。

def get_longest(s):
    longest = 0
    longestSubStr = ""
    i = 0
    
    while True:
        x = range(i, len(s) - 1)
        work = s[i]
        for n in x:
            if s[n] != s[n + 1]:            # Check where non-unique characters are found and build a substring
                work = work + s[n + 1]
            else:
                break

        if len(longestSubStr) < len(work):  # If the current test substring is longer than the previous substring, update the newest longest substring
            longestSubStr = work
            print("Current longest substring is", longestSubStr)

        i += 1                              # Keep incrementing the starting point in the substring until the righthand position is reached

        if i == len(s):
            break

    return longestSubStr

s = "abbcdffgciuyentuyydoiy"                # With this test string, the longest substring would be "fgciuyentuy"
print(get_longest(s))

在终端中运行此测试会产生以下输出。

craig@Vera:~/Python_Programs/CheckString$ python3 Longest.py 
Current longest substring is ab
Current longest substring is bcdf
Current longest substring is fgciuyentuy
fgciuyentuy

这只是实现解决方案的众多可能途径之一,因此请在问题和分配的参考框架中对其进行评估。

1赞 blhsing 11/16/2023 #3

解决线性时间复杂度问题的有效方法是,在循环访问字符时,将 FIFO 队列用作字符串的滑动窗口,并缩小窗口,直到当前字符不再是窗口中的重复字符。若要有效地查找当前字符是否在窗口中,请使用集合。OrderedDict,以便查找和窗口收缩都可以在恒定的平均时间复杂度下完成:

from collections import OrderedDict

def get_longest_unique_substring(s):
    window = OrderedDict()
    longest_end = longest_size = 0
    for index, char in enumerate(s):
        while char in window: # if the current character is in the window
            window.popitem(last=False) # shrink the sliding window
        window[char] = True # add the current character to the sliding window
        if (size := len(window)) > longest_size:
            longest_end = index + 1
            longest_size = size
    return s[longest_end - longest_size: longest_end]

演示:https://ideone.com/6UWdM4