【问题标题】:Python Subsequence of a String字符串的 Python 子序列
【发布时间】:2020-06-27 15:19:59
【问题描述】:

练习要求我编写一个程序。它写了

"给定一个字符串s和一个字符串t,检查s是否是t的子序列。
例如:"ac", "abcd" => True。”

所以我写了这个:

def isSubsequence(s, t):
        s, t = map(list, [s, t])
        for c in t:
            if c in s:
                s.pop(0)
        return not s

在大多数情况下都可以正常工作,除了一种情况:

s = "rjufvjafbxnbgriwgokdgqdqewn"
t = "mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq"

我不知道为什么我的代码在这个上不起作用。所以如果有人知道答案,请告诉我。

【问题讨论】:

  • 您的代码正在测试s 中的每个字符是否也在t以任意顺序 -- 这是一个简单的示例:isSubsequence('ab', 'acb') => True .在 Python 中有更简单的测试序列成员资格的方法,但由于这是一个练习,我不会只告诉你 ;-)
  • 为什么s.pop(0)?!
  • @Juniktw 我建议你看一个更简单的例子,比如isSubsequence('ab', 'bb')。您的代码目前为此返回True,这显然不是预期的结果...
  • 是的,它适用于简单的测试用例,但不适用于上述较大的测试用例。
  • @Juniktw 不,它适用于那种简单的情况。它应该返回False,因为'ab' 显然不是'bb' 的子序列。

标签: python python-3.x string


【解决方案1】:

你可以这样做:

def isSubsequence(s, t):
    s = list(s)
    for i,(a,b) in enumerate(zip(t,s)):
        if a != b:
            s.insert(i,'.')
    return len(t) == len(s)
    
print(isSubsequence('Apes are goo.', 'Apples are good.'))

输出:

True



您的情况是,特定的s 不是特定t 的子序列。为了证明这一点:

def isSubsequence(s, t):
    s = list(s)
    for i,(a,b) in enumerate(zip(t,s)):
        if a != b:
            s.insert(i,'.')
    print(t)
    print(''.join(s))

s = "rjufvjafbxnbgriwgokdgqdqewn"
t = "mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq"

isSubsequence(s, t)

输出:

mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq
......r...........................j.u...................f...............................................................v..............................j..................................................................................................a................f..b..............................................................................x............n...b....................g....................................................................................r...i.......................wgokdgqdqewn



更新包括@StevenRumbalski 在 cmets 给出的更简单的实现:

def isSubsequence(s, t, start=-1): 
    return all((start:=t.find(c, start+1)) > -1 for c in s)

【讨论】:

  • 另一个简单的实现(Python 3.8+)def isSubsequence(s, t, start=0): return all((start:=t.find(c, start)) > -1 for c in s)
  • @StevenRumbalski 这已经坏了,因为它会为isSubsequence('bb', 'abc') 返回True。请参阅this answer 了解算法的正确实现。
  • @ekhumoro:固定:def isSubsequence(s, t, start=-1): return all((start:=t.find(c, start+1)) > -1 for c in s)
【解决方案2】:

我想顺序也很重要

def isSubsequence(s, t): # order matters
    s, t = list(s), list(t)
    for c in s:
        if c in t:
            c_idx = t.index(c)
            t = t[c_idx:]
        else:
            return False
    return True 

【讨论】:

    【解决方案3】:
    def isSubsequence(s, t):
        start = -1
        for i in s:
          start = t.find(i, start + 1)
          if start == -1:
            return False
        return True
    

    【讨论】:

    • str.findstart 参数一起使用会更简单。如果结果是-1,则返回False,否则使用result + 1 作为下一个start 参数。
    • @RonieMartinez 这看起来很糟糕。你想要start = -1start = t.find(i, start + 1),同时删除start += 1
    【解决方案4】:

    如果这是一个练习,你可能应该自己弄清楚:),但既然你已经发布了你的尝试,请允许我提出这个可能对你有用的更简单的方法:

    from itertools import combinations
    
    def isSubsequence(s, t):
        return any(s == ''.join(c) for c in combinations(t, len(s)))
    

    它显然性能较差,但至少可能是一个有用的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 2011-04-10
      • 2014-03-07
      • 2023-04-03
      相关资源
      最近更新 更多