2012-03-24 116 views
0

我正在比較Java中的兩個字符串,以查看第一個字符串中有多少個字符顯示在第二個字符串中。下面是一些期望:Java - 計算在另一個字符串中顯示多少個字符

matchingChars("AC", "BA") → 1 
matchingChars("ABBA", "B") → 2 
matchingChars("B", "ABBA") → 1 

我的做法如下:

public int matchingChars(String str1, String str2) { 

    int count = 0; 

    for (int a = 0; a < str1.length(); a++) 
    {  
     for (int b = 0; b < str2.length(); b++) 

      { char str1Char = str1.charAt(a); 
      char str2Char = str2.charAt(b); 

       if (str1Char == str2Char) 
        { count++; 
         str1 = str1.replace(str1Char, '0'); 
        } 
      } 
    } 
    return count; 
    } 

我知道我的做法是不是最好的,但我認爲它應該這樣做。但是,對於

matchingChars("ABBA", "B") → 2 

我的代碼產生「1」而不是「2」。有沒有人有任何建議或建議?非常感謝你。

回答

0

很顯然,你必須確保你只算從串1 獨特字符你重複計算B因爲你每次出現在串計數B的兩次,一次1

0

嗯,你的代碼只顯示1,因爲這行:

str1 = str1.replace(str1Char, '0'); 

這是轉向「ABBA」到「A00A」 - 所以第二個B不會被看到。

也許你應該把第二個字符串轉換成HashSet<Character>,而不是...那麼你可以只使用類似:

int count = 0; 
for (int i = 0; i < str1.length; i++) 
{ 
    if (otherSet.contains(str1.charAt(i)) 
    { 
     count++; 
    } 
} 

目前還不清楚是什麼導致你從「ABBA」 /「來獲得CBCB「 - 如果它是2(因爲有2個B),那麼上述方法將起作用。如果是4(因爲第一個字符串中的每個2 B匹配第二個字符串中的2 B),那麼全部您需要做的是擺脫您的replace調用。

編輯:隨着澄清,它聽起來就像你可能只是這樣做:

for (int a = 0; a < str1.length(); a++) 
{  
    for (int b = 0; b < str2.length(); b++) 
    { 
     if (str1.charAt(a) == str2.charAt(b)) 
     { 
      count++; 
      // Terminate the inner loop which is iterating over str2, 
      // and move on to the next character in str1 
      break; 
     } 
    } 
} 
+0

嗨喬恩,我認爲它只取代當前索引的字符,而不是替換所有相同的字符,所以我期待在第一次檢查後看到A0BA。我沒有學到任何有關HashSet的知識,也不知道如何使用它。但是如果你願意,你可以請我走過去嗎? – 2012-03-24 22:00:50

+0

而「CBCB」應該爲2 B產生2。我們可以從字符串中提取字符並使用它們填充兩個ArrayLists嗎? – 2012-03-24 22:02:07

+0

@VũChâu:不,'replace'將會替換*所有的事件。在字符串中沒有「當前索引」這樣的概念。這聽起來好像不是改變字符串,只是用一個'break'語句打破內部循環就會更簡單,所以你轉到'str1'中的下一個字符。 – 2012-03-24 22:03:53

0

您的解決方案的工作原理,但二次。如果所有字符都低於256,那麼你可以做這樣的事情:

int matching(String s1, String s2) { 
int[] count1 = frequencies(s1); 
int[] count2 = frequencies(s2); 
sum = 0; 
for(int i = 0; i< 256; i++) { 
    sum += count1[i]*count2[i] != 0 ? Math.max(count1[i], count2[i]) : 0; 
} 
return sum; 
} 

int[] frequencies(String s) { 
int[] ret = new int[256]; 
for(char c : s) { 
    int[c]+=1; 
} 
} 

否則,你需要一個multiset

2

假設比較 「AABBB」 與 「AAAABBBCCC」 應返回15(2 * 3 + 3 * 3 + 0×3)然後:

對於每個串從字符串到的字符進行地圖字符數。 計算兩個映射的鍵集的交集。 對於密鑰集中的每個元素,累積值的乘積。打印結果。 這在兩個字符串的大小上是線性的。

1

可以提供工作代碼作業有問題嗎?

public long testStringCount() { 
    String a = "AABBBCCC"; 
    String b = "AAABBBDDDDD"; 

    Map<Character,Integer> aMap = mapIt(a); 
    Map<Character,Integer> bMap = mapIt(b); 

    Set<Character> chars = Sets.newHashSet(aMap.keySet()); 
    chars.addAll(bMap.keySet()); 

    long result = 0; 
    for (Character c : chars) { 
    Integer ac = aMap.get(c); 
    Integer bc = bMap.get(c); 
    if (null != ac && null != bc) { 
    result += ac*bc; 
    } 
    } 
    return result; 
} 

private Map<Character, Integer> mapIt(String a) { 
Map<Character,Integer> result = Maps.newHashMap(); 
for (int i = 0; i < a.length(); i++) { 
    Character c = a.charAt(i); 
    Integer x = result.get(c); 
    if (null == x) { 
    x = 0; 
    } 
    x++; 
    result.put(c, x); 
} 
return result; 
} 
相關問題