在 Java 中使用哈希表计算字符的出现次数

counting occurance of characters using hashtable in Java

我正在尝试计算字符串中每个字符的出现次数。 因此,如果我输入 aaabbbccc,我希望 o/p 为 {a=3, b=3, c=3} 但我会继续将其作为 {a=1, b=1, c=1} 作为我的输入哈希表包含方法失败和 returns 错误。代码有什么问题?

我也知道有一个和hashtable很像的HashMap集合。但是在我学习 java 时,我想对所有数据结构尝试相同的代码,只是为了了解方法。带有地图的代码与我在这里所做的没有太大区别,但这段代码仍然失败。而且我无法弄清楚代码中的错误在哪里。

我有以下代码:

Hashtable<Character, Integer> stringHash = new Hashtable<Character, Integer>();

这个stringHash是class级变量。

for(int i=0; i<s.length(); i++){
        if(stringHash ==null || stringHash.size()==0){
            stringHash.put(s.charAt(i), 1);
        }
        else{
            if(! stringHash.contains(s.charAt(i)) ){
                System.out.println(s.charAt(i));
                stringHash.put(s.charAt(i), 1);
            }
            else{
                int count = stringHash.get(s.charAt(i));
                stringHash.put(s.charAt(i), count++);
            }   
        }
        System.out.println(stringHash + " " + s.charAt(i) + "  "+ stringHash.contains(s.charAt(i)));
}

这段代码对我有用:

String s = "aaabbbccc";

Map<Character, Integer> stringHash = new HashMap<Character, Integer>();
for (char ch : s.toCharArray())
    stringHash.put(ch, stringHash.containsKey(ch) ? (stringHash.get(ch) + 1) : 1);

System.out.println(stringHash);
// output: "{a=3, b=3, c=3}"

我使用的是 Map<K, V> 而不是 HashTable<K, V>,但这更常见。

不鼓励调试我的代码问题,但在解决计算字符串中字符的一般问题的方式中,我可以建议一个更简单的方法:

public static int[] countCharacters( String s ){
    int[] count = new int[ 256 ];
    for( int xChar = 0; xChar < s.length(); xChar++ ) count[ s.charAt( xChar ) ]++;
    return count;
}   

这假定您有单字节字符。

尝试这样的事情....您的代码失败的原因是您检查的是 HashTable 上的 contains() 而不是它的 keySet。希望有帮助

 public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s = "aaaaabbcccc";
    Hashtable<Character, Integer> counter = new Hashtable<Character, Integer>();
    int count = 0;
    for(int i=0;i<s.length();i++){
        if(!counter.keySet().contains(s.charAt(i))){
            counter.put(s.charAt(i), 1);
        } else {
            count = counter.get(s.charAt(i));
            counter.put(s.charAt(i), ++count);
        }
    }

    for(char c:counter.keySet()) {
        System.out.println("Character : "+c+" - Occurences : "+counter.get(c));
    }
}

o/p

Character : b - Occurences : 2
Character : c - Occurences : 4
Character : a - Occurences : 5

为什么要用hashMap来统计字符出现次数? 我会像这样使用大小为 255 的整数数组:

    int[] counter = new int[256];
    String s = "aaabbbcccc";
    for(int i = 0; i < s.length(); i++){
        counter[s.charAt(i)]++;
    }

    for(int i = 0; i < counter.length; i++)
        if(counter[i] > 0)
            System.out.println(((char)i) + " occurs " + counter[i] + " times");

那个 coude 会给出一个输出:

a occurs 3 times
b occurs 3 times
c occurs 4 times

您的代码

if(stringHash ==null || stringHash.size()==0){
    stringHash.put(s.charAt(i), 1);
}

会抛出 NPE 如果 hashmap 不知何故为 null。幸运的是,您似乎已经正确地初始化了它。该块应该是

if(stringHash ==null){
    stringHash = new HashMap()
    stringHash.put(s.charAt(i), 1);
}

同样,这不会修复您的错误。您应该使用 containsKey 而不是 contains 来检查 HashTable 中的值。您要实现的内容可以总结为以下伪代码。

initialize hashmap
for each character c in inputString
  count = 0
  if hashmap has a key for c
     count = get value for c from hashmap
  end if
  put in to hashmap c, count + 1
end for

在 Java 中看起来像:

Map<Character, Integer> charCountMap = new HashMap<>();
for(char c : inputString.toCharArray()){
  int count = 0;
  if(charCountMap.containsKey(c)){
    count = charCountMap.get(c);
  }
  charCountMap.put(c,count+1);
}

或者喜欢冒险的人,这里是Java8版本

Map<Character,Long> map = s.chars().mapToObj(i->(char)i)
                                     .collect(Collectors
                                                .groupingBy(e -> e,
                                                   Collectors.counting()));
System.out.println(map);

最后,不要使用 HashTable 它是一个遗留问题 class,现在没人使用它了。坚持使用 HashMap 或其他类型的 Map 实现。

不要使用 Hashtable,你可以大大简化代码,像这样应该可以工作:

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

public class Main {

    public static void main(String[] args) {
        Map<Character, Long> countMap = count("aabbbcccc");
        for (Map.Entry<Character, Long> entry : countMap.entrySet()) {
            System.out
                    .println(MessageFormat.format("Char ''{0}'' with count ''{1}''", entry.getKey(), entry.getValue()));
        }
    }

    private static Map<Character, Long> count(String value) {
        Map<Character, Long> countMap = new HashMap<Character, Long>();

        if (StringUtils.isNotBlank(value)) {
            for (int i = 0; i < value.length(); i++) {
                Long count = countMap.get(value.charAt(i));

                count = count == null ? 1 : count + 1;
                countMap.put(value.charAt(i), count);
            }
        }

        return countMap;
    }
}