2012-04-01 175 views
0

我写了一小段代码,应该检测2个字符串中是否有相同位置的任何匹配字符。如果有,则将得分加1,如果有两个或更多连续匹配字符,则得分增加3,如果没有匹配的字符,则得分递减1. 问题是,当我尝试运行代码,它给了我一个错误:字符串索引超出范围。 什么可能是错误的?非常感谢你。while while循环中的字符串比较

def pairwiseScore(seqA, seqB): 
    count = 0 
    score = 0 
    while count < len(seqA): 
     if seqA[count] == seqB[count]: 
      score = score + 1 
      count = count + 1 
      while seqA[count] == seqB[count]: # This is the line the error occurs 
       score = score + 3 
       count = count + 1 
     elif seqA[count] != seqB[count]: 
      score = score - 1 
      count = count + 1 
    return score 
+0

“什么可能是错的?”你自己说过“串指数超出范围”。不要误解我的意思我明白这是作业,但谷歌是你的朋友,现在是时候让你的调试技巧能够正常运行了 – 2012-04-01 22:11:34

+0

对不起,我不知道这个错误的含义。据我所知,这意味着如果一个字符串是8个字符长,索引是[8],则会发生错误。但是,在我的代码中,索引不会超过字符串的长度。 – geekkid 2012-04-01 22:15:02

+0

@geekkid:看到我的答案。您正在索引字符串的长度。 – 2012-04-01 22:18:31

回答

0

索引编号为0至n。

len(someString) 

会给你的n + 1

假设你的字符串是长度10,索引是0,1,2,3,4,5,6,7,8,9

你的while循环检查计数的条件是< 10.到目前为止这么好。

好吧,现在让我们假设计数等于9.立即在第一个while循环内,您递增计数。

所以现在算= 10

现在试图访问someString [计]会给你一个IndexError因为指数只上升至9。

1

这两个字符串的长度是否相同?否则,你应该考虑使用类似:

while count < min(len(seqA), len(seqB)):

+0

是的,这两个字符串应该有相同的长度。但不是那么少,谢谢你的评论,因为我甚至不知道min函数存在:D。 – geekkid 2012-04-01 22:17:22

0

错误消息说,:你试图访问一个字符超出你的字符串的边界。试想一下:

>>> s = "hello" 
>>> len(s) 
5 
>>> s[4] 
'o' 

现在,当(在第一while循环的开始)count是1以下len(seqA),那么你就递增count,然后你做seqA[count]这将抛出此异常。

让我们假设你打电话pairwisescore("a", "a")

score = 0 
count = 0 
while count < len(seqA):     # 0 < 1 --> OK 
    if seqA[count] == seqB[count]:   # "a" == "a" --> OK 
     score = score + 1     # score = 1 
     count = count + 1     # count = 1 
     while seqA[count] == seqB[count]: # seqA[1] doesn't exist! 
0
def pairwiseScore(seqA, seqB): 
    count = 0 
    score = 0 
    isOne = False 
    isTwoOrMore = False 
    while count < min(len(seqA), len(seqB)): 
     if seqA[count] == seqB[count]: 
      if isTwoOrMore: 
       score = score + 3 
       count = count + 1 
      else: 
       if isOne: 
        isTwoOrMore = True 
       score = score + 1 
       count = count + 1 
       isOne = True 
     elif seqA[count] != seqB[count]: 
      score = score - 1 
      count = count + 1 
      isOne = False 
      isTwoOrMore = False 
    return score 

a = 'apple' 
b = 'aplle' 
print(pairwiseScore(a, b)) 

我觉得这一个解决这个问题,我添加了一个 “计数” bool变量。为了回答这个问题,你的程序没有比较第二个字符串的长度。

while count < min(len(seqA), len(seqB)): 
0

在第二个while循环必须测试计数小于LEN(seqA):

while count < len(seqA) and seqA[count] == seqB[count]: 
    ... 

和,也有其他可能的错误:如果seqB的长度小于长度seqA,你会再次看到运行时异常。所以,你应该改变count < len(seqA)count < min(len(seqA), len(seqB))的每一次发生。

0

的问题是,你这样做:

count = count + 1 

两个内while循环之前,在它的结束。但是,在再次检查len(seqA)之前,您继续使用seqA[count] - 因此,一旦它变得太高,Python将尝试读取seqA的末尾,并且您会看到该错误(如果在检查条件后再次检查递增,循环将结束)。

使用Python的for循环将得到解决这样的错误,因为Python会为你管理count

for a,b in zip(seqA, seqB): 
    if a == b: 
     score += 1 

您可以随时追踪轻松实现额外的点位在此是否以前字符是匹配的,而不是试图找出这个之后有多少个。你保持更新的布尔变量last_matched将有助于此。

1

此外,zip函数可能在这里派上用场来配对每个单词中的字母。这是一个python builtin。例如

def letter_score(s1, s2): 
    score = 0 
    previous_match = False 

    z = zip(s1, s2) 
    for pair in z: 
     if pair[0] == pair[1]: 
      if previous_match: 
       score += 3 
      else: 
       score += 1 
       previous_match = True 
     else: 
      score -= 1 
      previous_match = False 
    return score