2017-04-18 51 views
-1

我寫了一小段代碼來檢查字符串相似性百分比。它看起來像:字符串相似性算法返回假值

int similarity(std::string s1, std::string s2) { 
    int size = 0, sim = 0; 
    if(s1==s2) { 
     sim = 100; 
    } else { 
     if(s1 > s2) 
      size = s2.size(); 
     else 
      size = s1.size(); 

     for(int i = 0; i != (size); ++i) { 
      if(s1[i] == s2[i]) 
       ++sim; 
     } 
    } 
    return (sim/s2.size()>s1.size()?s2.size():s1.size())*10; 
} 

和我一樣,(我已經添加了這些「DDDD」,使字符量= 10)的主要功能測試:

std::cout << "Similarity of gananadddd and bananadddd (%): " << std::endl; 
std::cout << similarity("gananadddd", "bananadddd") << "%" << std::endl; 

和控制檯輸出:

Similarity of gananadddd and bananadddd (%): 
100% 

因此,我認爲我的代碼不能很好地工作,因爲:

  • 百分比不應該是100%,因爲只改變了一個字母。
  • 在我注意到此輸入百分比可能爲1000%之前的某個時間,如果我將return (sim/s2.size()>s1.size()?s2.size():s1.size())*10;更改爲 return (sim/s2.size()>s1.size()?s2.size():s1.size())*100;。實際上它應該是100!

我會很高興的是有人會指出我犯了錯誤的地方。另外,我可以考慮改變算法

編輯:

我修改的代碼位:

double similarity(std::string s1, std::string s2) { 
    int size = 0, sim = 0; 
    if(!s1.compare(s2)) { 
     return 100; 
    } else { 
     if(!s2.compare(s1) < 0) 
      size = s2.size(); 
     else 
      size = s1.size(); 

     for(int i = 0; i != (size); ++i) { 
      if(s1[i] == s2[i]) 
       ++sim; 
     } 
    } 
    return sim/((s2.size()>s1.size())?s2.size():s1.size())*100; 
} 

..和現在得到0%...

+5

'SIM/s2.size()'使用整數除法和產量'0'始終。即使沒有這些,爲了實現它,它需要'sim> s1.size()* s2。大小()',我不明白怎麼可能發生 – user463035818

+0

後三次(也許四個)閱讀它,我想我知道什麼樣的回報應該做的。你想寫'sim /((s2.size()> s1size)?s2.size():s1.size())'?注意括號中的三元組。不是100%肯定的,但我相信'/'比'>'具有更高的優先級。 – user463035818

+0

... btw返回一個'int'沒有太大的意義。我會直接返回'sim'並讓用戶根據需要計算百分比,或者返回一個'double' – user463035818

回答

1

您可能需要使用Levenshtein Distance計算相似度,然後根據您比較的字符串計算相似度。

根據您的代碼,由於遞歸Java實現

public static void main(String[] args) { 
    char[] A = "hello".toCharArray(); 
    char[] B = "hallo".toCharArray(); 
    int ld = LD(A, B, A.length, B.length); 
    System.out.println(ld); 
} 

public static int LD(char[] A, char[] B, int n, int m) { 
    if (n == 0 && m == 0) return 0; 
    if (n == 0) return m; 
    if (m == 0) return n; 

    return min(
      LD(A, B, n - 1, m - 1) + A[n - 1] == B[m - 1] ? 0 : 1, 
      LD(A, B, n, m - 1) + 1, 
      LD(A, B, n - 1, m) + 1 
    ); 
} 

private static int min(int a, int b, int c) { 
    return Math.min(a, Math.min(b, c)); 
} 

C++

int similarity(std::string s1, std::string s2) { 
    int distance = LD(s1, s2, s1.size(), s2.size()); 
    return distance/(max(s1.size(), s2.size())); 
} 

int LD(std::string A, std::string B, int n, int m) { 
    if (n == 0 && m == 0) return 0; 
    if (n == 0) return m; 
    if (m == 0) return n; 

    return min(
      LD(A, B, n - 1, m - 1) + A[n - 1] == B[m - 1] ? 0 : 1, 
      LD(A, B, n, m - 1) + 1, 
      LD(A, B, n - 1, m) + 1 
    ); 
} 

int min(int a, int b, int c) { 
    return min(a, min(b, c)); 
} 
+0

真酷!謝謝! –

-2

使用功能

std::string::compare() 

如果你運行;如果s是

等於零,如果s和t相等,小於零

如果s小於T,

大於零:

if (!s.compare(t)) { 
    // 's' and 't' are equal. 
} 

它返回int大於t。

爲了詳細說明用例,如果您感興趣的是兩個字符串在不同情況下彼此相關(更多或更少),compare()會很有用。

+0

我試圖替換我的比較例程,它不起作用。 –