简体   繁体   中英

Given 2 strings, return number of positions where the two strings contain the same length 2 substring

here is my code:

def string_match(a, b):
  count = 0

  if len(a) < 2 or len(b) < 2:
    return 0

  for i in range(len(a)):
    if a[i:i+2] == b[i:i+2]:
      count = count + 1
  return count

And here are the results:

在此处输入图像描述

Correct me if I am wrong but, I see that it didn't work probably because the two string lengths are the same. If I were to change the for loop statement to:

for i in range(len(a)-1):

then it would work for all cases provided. But can someone explain to me why adding the -1 makes it work? Perhaps I'm comprehending how the for loop works in this case. And can someone tell me a more optimal way to write this because this is probably really bad code. Thank you!

But can someone explain to me why adding the -1 makes it work?

Observe:

test = 'food'
i = len(test) - 1
test[i:i+2] # produces 'd'

Using len(a) as your bound means that len(a) - 1 will be used as an i value, and therefore a slice is taken at the end of a that would extend past the end. In Python, such slices succeed , but produce fewer characters.

String slicing can return strings that are shorter than requested. In your first failing example that checks "abc" against "abc", in the third iteration of the for loop, both a[i:i+2] and b[i:i+2] are equal to "c", and therefore count is incremented.

Using range(len(a)-1) ensures that your loop stops before it gets to a slice that would be just one letter long.

Since the strings may be of different lengths, you want to iterate only up to the end of the shortest one. In addition, you're accessing i+2 , so you only want i to iterate up to the index before the last item (otherwise you might get a false positive at the end of the string by going off the end and getting a single-character string).

def string_match(a: str, b: str) -> int:
    return len([
        a[i:i+2]
        for i in range(min(len(a), len(b)) - 1)
        if a[i:i+2] == b[i:i+2]
    ])

(You could also do this counting with a sum , but this makes it easy to get the actual matches as well!)

You can use this:

def string_match(a, b):
    if len(a) < 2 or len(b) < 0:
        return 0

    subs = [a[i:i+2] for i in range(len(a)-1)]
    occurence = list(map(lambda x: x in b, subs))

    return occurence.count(True)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM