4

我有一个文件,它在表单key/value对中具有字符串,例如人员和计数,例如

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

在输出中,我应该根据键总结所有计数值,因此对于我们的示例输出将是

“雷吉,19 岁” “珍妮,25 岁​​”

这是我的方法:

  1. 读取每一行,并使用扫描仪为每一行获取密钥和计数并,作为分隔符
  2. 现在看看 key 之前是否已经存在,如果没有,则将 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。

还是建议的方法是最佳方法,还是有办法进一步提高性能。

4

6 回答 6

8

由于这几乎可以肯定是一个学习练习,我将远离编写代码,让您享受所有乐趣。

创建一个HashMap<String,Integer>. 每次看到键/值对时,检查哈希映射是否具有键的值(使用'containsKey(key)')。如果是,则使用 获取该旧值get(key),添加新值,然后使用 将结果存储回来put(key, newValue)。如果密钥还没有,添加一个新的 - 再次,使用put. int如果String value(用于此),请不要忘记做出Integer.valueOf(value)判断。

就优化而言,此时的任何优化都为时过早:它甚至不起作用!但是,很难获得比您拥有的单个循环更快的速度,这也相当简单。

于 2013-02-08T22:17:21.433 回答
2

对于阅读,我个人会使用:

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

于 2013-02-08T22:18:02.253 回答
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));
        }
    }
于 2013-02-08T22:19:19.447 回答
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通常用于解析,但这里的解析看起来并不复杂,只是字符串的拆分。

于 2013-02-08T22:43:06.733 回答
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");
        }
    }
于 2015-10-20T22:00:12.617 回答
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));
    }
于 2017-05-12T05:11:31.863 回答