为什么代码对长度相同的字符串不起作用?

2024-04-25 03:34:06 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是我编写的代码,它计算长度为2的子字符串的数量,这些子字符串对于两个输入都是公共的字符串。还有子字符串应位于两个字符串中的同一位置。你知道吗

def string_match(a, b):
  count=0
  shorter=min(len(a),len(b))
  for i in range(shorter):
    if(a[i:i+2]==b[i:i+2]):
      count=count+1
    else:
      continue
  return count

对于长度不同的字符串,代码运行良好,但是对于长度相同的字符串,代码给出了错误的答案。例如:“abc”和“abc”应返回2,但返回3;“abc”和“axc”应返回0,但返回1。 上述问题可以通过将range(shorter)改为range(shorter-1)来解决,但我不明白为什么? 如果可能的话,建议我修改上面的代码,不管两个字符串中的位置如何,都可以计算相同的子字符串。你知道吗

提前谢谢!你知道吗


Tags: 字符串代码infor数量stringlendef
3条回答

检查for循环

for i in range(shorter):
    if a[i:i+2]==b[i:i+2]:
        count=count+1
    else:
        continue

^{}默认从0到n-1。那么在n-1的情况下会发生什么呢?您的循环正在尝试访问第n-1个到第n+1个字符。但是较小的字符串只有n个字符。所以Python只返回那个字母而不是两个字母,所以两个长度相等的字符串,最后一个字符相同,就会给出一个假阳性。这就是为什么range(shorter - 1)是必要的。你知道吗

而且continue的使用是多余的,因为默认情况下循环将继续

要在字符串中的任何位置找到长度为2的子字符串,这就足够了

def string_match(string1, string2):
    string1subs = [string1[i:i+2] for i in range(len(string1) - 1)]
    count = 0
    for i in range(len(string2) - 1):
        if string2[i:i+2] in string1subs: count += 1
    return count

创建一个列表string1subs,其中包含string1中长度为2的所有子字符串。然后循环遍历string2中长度为2的所有子串,并检查它是否是string1的子串。如果您喜欢更简洁的版本:

def string_match(string1, string2):
    string1subs = [string1[i:i+2] for i in range(len(string1) - 1)]
    return sum(string2[i:i+2] in string1subs for i in range(len(string2) - 1))

使用^{}的完全相同的版本,并且在Python中,True等于1。你知道吗

最好的方法是根本不使用任何索引访问:

def string_match(a, b):
    count = 0
    equal = False
    for c, d in zip(a,b):
        count += equal and c == d
        equal = c == d
    return count

或使用生成器表达式:

from itertools import islice
def string_match(a, b):
    return sum(a1 == b1 and a2 == b2
        for a1, a2, b1, b2 in zip(a, islice(a,1,None), b, islice(b,1,None)))

一些好的旧打印调试应该让事情更清楚:

#!/usr/bin/env python2
#coding=utf8

def string_match(a, b):
    count=0
    shorter=min(len(a),len(b))
    print 'comparing', a, b
    for i in range(shorter):
        x = a[i:i+2]
        y = b[i:i+2]
        print 'checking substrings at %d: ' % i, x, y
        if x == y:
            count=count+1
        else:
            continue
    return count


for a, b in (('abc', 'abc'), ('abc', 'axc')):
    count = string_match(a,b)
    print a, b, count

以及输出:

so$ ./test.py 
comparing abc abc
checking substrings at 0:  ab ab
checking substrings at 1:  bc bc
checking substrings at 2:  c c
abc abc 3
comparing abc axc
checking substrings at 0:  ab ax
checking substrings at 1:  bc xc
checking substrings at 2:  c c
abc axc 1

看到问题了吗?你总是在最后比较长度为1的子串。这是因为'abc'[2:4]只会给你'c'。你知道吗

因此,您需要提前一步结束(或者更一般地说,在比较长度为n的子字符串时,提前n-1步)。这正是您的-1更改所能做的,这就是它有帮助的原因。你知道吗

随着-1的变化:

#!/usr/bin/env python2
#coding=utf8

def string_match(a, b):
    count=0
    shorter=min(len(a),len(b))
    print 'comparing', a, b
    for i in range(shorter-1):
        x = a[i:i+2]
        y = b[i:i+2]
        print 'checking substrings at %d: ' % i, x, y
        if x == y:
            count=count+1
        else:
            continue
    return count


for a, b in (('abc', 'abc'), ('abc', 'axc')):
    count = string_match(a,b)
    print a, b, count

以及新的输出:

so$ ./test.py 
comparing abc abc
checking substrings at 0:  ab ab
checking substrings at 1:  bc bc
abc abc 2
comparing abc axc
checking substrings at 0:  ab ax
checking substrings at 1:  bc xc
abc axc 0

相关问题 更多 >