【问题标题】:How to ignore space, capital letters and punctuation in string using HashMap?如何使用 HashMap 忽略字符串中的空格、大写字母和标点符号?
【发布时间】:2018-03-21 20:58:08
【问题描述】:

您好,我正在尝试编写程序,该程序使用 HashMap 计算给定字符串中的所有字符,然后在控制台上打印结果,例如:

{a=2, s=2, k=1, m=1, o=1}

到目前为止,我有这样的事情:

public void result(String sentence) {
    int value;
    HashMap<Character, Integer> mp = new HashMap<Character, Integer>();
    for (int i = 0; i < sentence.length(); i++) {
        if (mp.containsKey(sentence.charAt(i))) {
            value = mp.get(sentence.charAt(i));
            value++;
            mp.put(sentence.charAt(i), value);

        } else {
            mp.put(sentence.charAt(i), 1);
        }
    }

    System.out.print(mp);
}

我想问我如何忽略给定字符串中的空格、大写字母和标点符号。 所以它不会显示在结果中?

希望有人能帮助我,谢谢!

【问题讨论】:

  • 您不能在地图内执行此操作。在与地图交互之前,您必须自己对每个角色执行此操作。
  • if (Character.isLowerCase(sentence.charAt(i))) { /* add it to the map */ }
  • @shmosel 仅在他实际上想要忽略大写字符而不是不区分大小写时才有效。

标签: java string collections hashmap


【解决方案1】:

我建议在将不需要的字符传递到HashMap 之前过滤掉它。

例如,

sentence = sentence.replaceAll("[^a-z]", "");

将删除除小写字母以外的任何内容,并且

sentence = sentence.replaceAll("[^a-z0-9]", "");

会留下小写字母和数字。

如果你想将大写字母转换为小写而不是忽略它们,那么首先使用

sentence = sentence.toLowerCase();

【讨论】:

  • 谢谢!你救了我! :) 不知道Java有这个功能...
【解决方案2】:

您可以检查当前字符的 ascii 值,如果它在给定范围 'a' (97) 和 'z' (122) 内,则将其添加到地图中,否则忽略它。

    if (mp.containsKey(sentence.charAt(i))) {
        ...
    } else if(sentence.charAt(i) >= 'a' || sentence.charAt(i) <= 'z') {
        mp.put(sentence.charAt(i), 1);
    } else {
        System.out.println("Ignoring - " + sentence.charAt(i));
    }

这将防止对句子进行任何额外的遍历,并在必须创建地图之前进行清理。 O(1)

【讨论】:

    【解决方案3】:

    这就是我处理任务的方式:

    public static void main(String[] args) {
        String source = "Here comes another challenger!";
        Map<Character, Integer> characterCounts = countCharacters(source);
        System.out.println("Source string \"" + source + "\" gives map:\n"
                + characterCounts);
    }
    
    public static Map<Character, Integer> countCharacters(String source) {
        Map<Character, Integer> characterCounts = new HashMap<>(64);
        source.chars().map(LetterCounter::lowercaseCharacter).filter(
                LetterCounter::isCharactedCounted).forEach(c
                        -> characterCounts.merge((char) c, 1, (o, n) -> o + 1));
        return characterCounts;
    }
    
    public static int lowercaseCharacter(int characterValue) {
        char character = (char) characterValue;
        return (int) Character.toLowerCase(character);
    }
    
    public static boolean isCharactedCounted(int character) {
        if (character >= 'a' && character <= 'z') {
            return true;
        }
        return false;
    }
    

    运行示例main 方法给出输出:

    Source string "Here comes another challenger!" gives map:
    {a=2, c=2, e=6, g=1, h=3, l=2, m=1, n=2, o=2, r=3, s=1, t=1}
    

    countCharacters 方法正在创建一个在给定字符串中找到的字符的IntStream,但这只是一种优雅/紧凑/懒惰的方式,与您在 for 循环中所做的事情完全相同。 Stream.map 方法调用lowercaseCharacter(int)int 字符值转换为小写字符int 值。然后filter 方法丢弃所有导致isCharactedCounted 方法返回false 的字符,因为我们不想要这些字符。然后forEach 用于处理我们感兴趣的字符串中的每个字符(每次在字符串中找到字符时都会调用forEach 中的代码)。 Map.merge 方法只是一种优雅/紧凑/懒惰的方式,可以完全按照您对 get,++,put 代码所做的工作。然后返回完成的地图。

    您可以自定义isCharacterCounted 方法以满足您的需求。请注意,此方法采用int 原语而不是char(因为String.chars() 方法返回int 的流而不是char 的流)。但是,在 Java 中,char 实际上只是 int,所以两者基本上是可以互换的,只要您记得在需要时使用正确的类型转换。 (请注意,在对Map.merge 的调用中,我们必须将int c 转换为(char) c,因为地图需要Character,而int 不能自动装箱为Character。我们需要创建实用方法lowercaseCharacterint 字符值转换为小写int 字符值。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 2017-08-23
      • 2018-12-13
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多