2015-12-09 66 views
1

我想有以下几点:比较两个字符串的相似性在Python

Input: ("a#c","abc") 
Output: True 

Input:("a#c","abd") 
Desired Output: False 
Real Output: True 

所以该函数返回true,如果两个字符串的长度相同,如果他们通过#字符,它表示只有不同为随机字符。 如果不是,我希望它返回False。

该功能应该改变什么?

def checkSolution(problem, solution): 

    if len(problem) != len(solution): 
     return False 

    if len(problem) == len(solution): 
     for i, c in zip(problem, solution): 
      if i != c: 
       return False 

      if i == c or "#" == c: 
       return True 

print (checkSolution("a#c","abc")) 

print (checkSolution("a#c","abd")) 
+2

出了什么问题?首先是缩进;) –

+3

也许,很好的答案已经在这里:http://stackoverflow.com/questions/1471153/string-similarity-metrics-in-python –

+1

注意审稿人:虽然罗马提供的链接有很多更好的方法比较字符串的相似性,它实际上并没有回答为什么他当前的解决方案不起作用的问题 – Foon

回答

2

现在你只是测试长度和首字符匹配。

for i, c in zip(problem, solution): 
    if i != c: 
     # that's the first set of chars, but we're already returning?? 
     return False 

    if i == c or "#" == c: 
     # wildcard works here, but already would have failed earlier, 
     # and still an early return if it IS true! 
     return True 

相反,你需要经过整个字符串,返回的结果,或使用all来为你做它。

if len(problem) == len(solution): 
    for p_ch, s_ch in zip(problem, solution): 
     if p_ch == "#": # wildcard 
      continue # so we skip testing this character 
     if p_ch != s_ch: 
      return False # This logic works now that we're skipping testing the "#" 
    else: # if we fall off the bottom here 
     return True # then it must be equal 
else: 
    return False 

或一条线:

return len(problem) == len(solution) and \ 
     all(p_ch==s_ch or p_ch=="#" for p_ch, s_ch in zip(problem, solution) 

,或者如果你真的疯了(读:你喜欢的正则表达式的方法太多了),你可以这样做:

def checkSolution(problem, solution): 
    return re.match("^" + ".".join(map(re.escape, problem.split("#"))) + "$", 
        solution) 
+0

谢谢:)我现在明白我的错误。 – user5562898

2

您只检查第一个字符。如果第一个字符相同或者它是#,则不应返回True,但应继续查找第一个不匹配项,并仅在for循环外返回True

的第二个问题是,在你的测试用例变量c是永远'#',因为iproblem一个字符,而csolution一个字符。

def checkSolution(problem, solution): 
    if len(problem) != len(solution): 
     return False 
    for i, c in zip(problem, solution): 
     if i != '#' and c != '#' and i != c : 
      return False 
    return True 
0

正如在评论中指出的那样,您的缩进会被忽略,应该修正。

if len(problem) == len(solution): 
    # in the line below, 
    # 'i' will contain the next char from problem 
    # 'c' will contain the next char from solution 
    for i, c in zip(problem, solution): 
     # in this line, if they're not equal, you return False 
     # before you have a chance to look for the wildcard character 
     if i != c: 
      return False 
     # ...and here you'd fail anyway, because you're testing 
     # the character from the solution string against the wildcard... 
     if i == c or "#" == c: 
      return True 
# ...while in your test, you pass the wildcard in as part of the problem string. 
print (checkSolution("a#c","abc")) 
0

您的功能的一行版本:

def check_solution(problem, solution): 
    return (len(problem) == len(solution) and 
      all(ch==solution[i] for i, ch in enumerate(problem) if ch != '#')) 

测试:

>>> check_solution("a#c", "abc") 
True 
>>> check_solution("a#c", "abd") 
False 
+1

感谢您的输入。它非常优雅。自从我开始编程以来,了解我应该努力的事情非常有帮助。 – user5562898