2015-12-09 67 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