1

The exercise asks me to write a program. It wrote

"Given a string s and a string t, check if s is a subsequence of t.
For example: "ac", "abcd" => True."

So I wrote this:

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

It worked ok in most cases except one:

s = "rjufvjafbxnbgriwgokdgqdqewn"
t = "mjmqqjrmzkvhxlyruonekhhofpzzslupzojfuoztvzmmqvmlhgqxehojfowtrinbatjujaxekbcydldglkbxsqbbnrkhfdnpfbuaktupfftiljwpgglkjqunvithzlzpgikixqeuimmtbiskemplcvljqgvlzvnqxgedxqnznddkiujwhdefziydtquoudzxstpjjitmiimbjfgfjikkjycwgnpdxpeppsturjwkgnifinccvqzwlbmgpdaodzptyrjjkbqmgdrftfbwgimsmjpknuqtijrsnwvtytqqvookinzmkkkrkgwafohflvuedssukjgipgmypakhlckvizmqvycvbxhlljzejcaijqnfgobuhuiahtmxfzoplmmjfxtggwwxliplntkfuxjcnzcqsaagahbbneugiocexcfpszzomumfqpaiydssmihdoewahoswhlnpctjmkyufsvjlrflfiktndubnymenlmpyrhjxfdcq"

I don't know why my code didn't work on this one. So if someone knows the answer, please tell me.

5
  • Your code is testing whether every character in s is also in t in any order -- here's a simple example: isSubsequence('ab', 'acb') => True. There are easier ways of testing sequence membership in Python but since it's an exercise I'm not going to just tell you ;-) Commented Jun 27, 2020 at 15:25
  • Why s.pop(0)?! Commented Jun 27, 2020 at 15:26
  • @Juniktw I suggest you look at a simpler example like isSubsequence('ab', 'bb'). Your code currently returns True for that, which is obviously not the desired result... Commented Jun 27, 2020 at 15:35
  • Yes it worked for simple test cases but not working for the larger test case as above. Commented Jun 27, 2020 at 15:40
  • 2
    @Juniktw No, it does not work for that simple case. It should return False, since 'ab' is clearly not a subsequence of 'bb'. Commented Jun 27, 2020 at 15:44

3 Answers 3

2

Here is what you can do:

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

Output:

True



Your case is that that specific s is not a subsequence of that specific t. To prove it:

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)

Output:

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



UPDATED to include simpler implementation given by @StevenRumbalski at the comments:

def isSubsequence(s, t, start=-1): 
    return all((start:=t.find(c, start+1)) > -1 for c in s)
Sign up to request clarification or add additional context in comments.

3 Comments

Another simple implementation (Python 3.8+) def isSubsequence(s, t, start=0): return all((start:=t.find(c, start)) > -1 for c in s)
@StevenRumbalski That is broken, since it will return True for isSubsequence('bb', 'abc'). See this answer for a correct implementation of the algorithm.
@ekhumoro: fixed: def isSubsequence(s, t, start=-1): return all((start:=t.find(c, start+1)) > -1 for c in s)
1

I suppose the order also matters

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 

Comments

0
def isSubsequence(s, t):
    start = -1
    for i in s:
      start = t.find(i, start + 1)
      if start == -1:
        return False
    return True

2 Comments

It's smpler to use str.find with a start argument. If the result is -1, return False, otherwise use result + 1 for the next start argument.
@RonieMartinez That looks broken. You want start = -1 and start = t.find(i, start + 1), and also remove start += 1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.