2013-02-08 59 views
4

我有有字符串形式key/value對喜歡的人的文件和計數,例如將HashMap的:添加與普通鍵的值,並打印出來

"Reggy, 15" 
"Jenny, 20" 
"Reggy, 4" 
"Jenny, 5" 

,並在輸出我都總結基於密鑰計數值,所以在我們的例子輸出是

「Reggy,19」 「珍妮,25」

這裏是我的方法:

  1. 閱讀每行和每行獲取密鑰,並使用掃描儀,並具有,作爲分隔符
  2. 現在看關鍵是已經存在之前,如果然後只需添加currentValues到previousValues如果沒有的話拿CurrentValue的作爲HashMap中的值數。

示例實現:

public static void main(final String[] argv) { 
    final File file = new File("C:\\Users\\rachel\\Desktop\\keyCount.txt"); 

    try { 
     final Scanner scanner = new Scanner(file); 

     while (scanner.hasNextLine()) { 
      if (scanner.hasNext(".*,")) { 
       String key; 
       final String value; 

       key = scanner.next(".*,").trim(); 

       if (!(scanner.hasNext())) { 
        // pick a better exception to throw 
        throw new Error("Missing value for key: " + key); 
       } 

       key = key.substring(0, key.length() - 1); 
       value = scanner.next(); 

       System.out.println("key = " + key + " value = " + value); 
      } 
     } 
    } catch (final FileNotFoundException ex) { 
     ex.printStackTrace(); 
    } 
} 

部分我不明白的是如何,而在閱讀他們,並基於該創建HashMap的劃分鍵/值對。

此外,這種方法是建議最佳的方法,或者是否有一種方法來提高性能。

+0

沒有嘗試的'#的java.util.HashMap的containsKey(),把(),獲得()'? – ogzd 2013-02-08 22:14:28

+3

這是「僞代碼」:-) http://en.wikipedia.org/wiki/Pseudocode – dnault 2013-02-08 22:14:57

回答

8

因爲這幾乎肯定是一種學習練習,所以我會遠離編寫代碼,讓您充滿樂趣。

創建一個HashMap<String,Integer>。每次您看到一個鍵/值對時,檢查哈希映射是否具有該鍵的值(使用'containsKey(key)')。如果是,則使用get(key)獲取舊值,添加新值,並使用put(key, newValue)將結果存回。如果密鑰尚未存在,請再添加一個新密鑰 - 使用put。如果String value(請使用Integer.valueOf(value)表示),請不要忘記製作一個int

就優化而言,在這一點上的任何優化都是不成熟的:它甚至不能工作!但是,要獲得比您擁有的單個循環更快的速度是很困難的,這也很簡單。

+0

我知道這個部分的實現,但問題是當我讀取鍵/值對數據時。 – Rachel 2013-02-08 22:23:55

+0

@Rachel這應該是如果您使用'Scanner'來讀取行,然後使用'split',請查看[ideone上的這個示例](http://ideone.com/3zeQ3A)進行演示。 – dasblinkenlight 2013-02-08 22:41:58

+0

謝謝,我現在明白了。 – Rachel 2013-02-08 23:00:15

2

用於讀取,就個人而言,我會使用:

Scanner.nextLine()String.split(",")Integer.valueOf(value)

+0

這應該是一個評論 – mre 2013-02-08 22:18:25

+0

應該拆分(「,」),因爲它期望一個字符串。 – Sednus 2013-02-08 22:21:51

2

試試這個:

Map<String, Long> map = new HashMap<String, Long>(); 

while (scanner.hasNextLine()) { 
     if (scanner.hasNext(".*,")) { 
      .... 
      if(map.containsKey(key)) 
       map.put(key, map.get(key) + Long.valueOf(value)); 
      else 
       map.put(key, Long.valueOf(value)); 
     } 
    } 
+0

爲什麼很長,當然這些數字看起來像年齡。不應該擔心超過Integer的值 – Sednus 2013-02-08 22:23:37

+1

看起來像年齡?然後這兩個Reggie和Jenny不是同一個人:-)這是一個完全不同的情況。除了'貌似'不是一個好的論點。 – ogzd 2013-02-08 22:25:43

+0

然而,這應該明智地挑選出來。 – Sednus 2013-02-08 22:28:35

2

最簡單的方法我能想到的分裂值:

BufferedReader reader = new BufferedReader(new FileReader(file)); 
    Map<String, Integer> mapping = new HashMap<String,Integer>(); 

    String currentLine; 
    while ((currentLine = reader.readLine()) != null) { 

     String[] pair = currentLine.split(","); 

     if(pair.length != 2){ //could be less strict 
      throw new DataFormatException(); 
     } 

     key = pair[0]; 
     value = Integer.parseInt(pair[1]); 
     if(map.contains(key)){ 
      value += map.get(key); 
     } 
     map.put(key,value); 
    } 

這是最可能不是性能方面最有效的方式,但非常簡單。 Scanner通常用於解析,但這裏的解析看起來並不複雜,只是字符串的分割。

0

種類遲而乾淨的解決方案,時間複雜度爲O(n)。該解決方案繞過這類陣列

public class Solution { 

    public static void main(String[] args) { 
    // Anagram 
      String str1 = "School master"; 
      String str2 = "The classroom"; 


      char strChar1[] = str1.replaceAll("[\\s]", "").toLowerCase().toCharArray(); 
      char strChar2[] = str2.replaceAll("[\\s]", "").toLowerCase().toCharArray(); 

      HashMap<Character, Integer> map = new HashMap<Character, Integer>(); 

      for (char c : strChar1) { 
       if(map.containsKey(c)){ 
        int value=map.get(c)+1; 
        map.put(c, value); 
       }else{ 
        map.put(c, 1); 
       } 

      } 

      for (char c : strChar2) { 
       if(map.containsKey(c)){ 
        int value=map.get(c)-1; 
        map.put(c, value); 
       }else{ 
        map.put(c, 1); 
       } 
      } 

      for (char c : map.keySet()) { 
       if (map.get(c) != 0) { 
        System.out.println("Not anagram"); 
       } 
      } 
        System.out.println("Is anagram"); 
     } 
    } 
0
public Map<String, Integer> mergeMaps(@NonNull final Map<String, Integer> mapOne, 
              @NonNull final Map<String, Integer> mapTwo) { 
     return Stream.of(mapOne.entrySet(), mapTwo.entrySet()) 
       .flatMap(Collection::stream) 
       .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::sum)); 
    }