java - HashMap 以小数形式打印字母频率?

标签 java foreach hashmap

我有这个代码:

public String LetterFreq(String t) {
HashMap<Character,Double> map= new HashMap<Character, Double>();
for(int i=0;i< t.length();i++) {
    char c=  t.charAt(i);
    Double val = map.get(c);
    if(val!= null) {
        map.put(c,new Double(val +1));
    }
    else {
        map.put(c, 1.0);
    }
    
    
}
for (Entry<Character, Double> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + (entry.getValue()/t.length()));
}

在此代码中,它会迭代我给出的字符串中的每个字母,并将计数映射到键(如果有多个字母则递增)。此外,在打印该行时,它会将数字(计数)除以整个字符串的长度。我遇到的问题是,当我在里面输入文本时,我希望输出如下所示:

letter: decimalvalue
letter: decimalvalue

但我得到的是这个:

: decimal value
letter: decimavalue
letter:decimalvalue...

一些变化,无论我有一个没有字母的空格,但它给出了一个十进制值,我不明白为什么?

更新:

我假设这与字符串中的空格有关,但是当我输入像 thisisjulz 这样的文本时,我们可以在这里看到字母 s 出现了 2/10,这应该意味着 0.2但相反,我的代码在我没有输入的空格中注册了空格,如上面引用的示例所示,并将其计为 1 个字符空格。有什么方法可以实现分隔符或其他东西来确保它只计算具有值的字符?

Updatev2:这是我从中获取“字符串 t”的位置以及这一切是如何组合在一起的: alice 将我输入到控制台的值发送给 eve,Eve 函数所做的就是 LetterFreq(tex);

 public void Alice() 
{
System.out.println("Would you like to encrpyt a message or quit?");
System.out.println("To Encrypt press enter 9.");
System.out.println("If you wish to quit enter 0.");
System.out.println("If you made a mistake and want to go back to the main menu press 7.");

Scanner q = new Scanner(System.in);
   
switch (q.nextInt()) 
{
    case 0:
    System.out.println ("Thank you and goodbye.");
    break;

    case 9:
    System.out.println ("Please enter text:");
 
    
    String tex ="";
    String line;
    while (in.hasNextLine()) {
        line = in.nextLine();
        if (line.isEmpty()) {
            break;
        }
        tex += line + "\n";
    }
  
       tex= Encryption(tex);
       System.out.println(tex+"\n");
       System.out.println("Would you like to simulate Bob Or Eve? ");
       System.out.println("Enter 5 for Bob, 6 For Eve");
         
       in.hasNextInt();
       if(in.nextInt()==5) {
           tex= tex.replaceAll(" ", "");
          Bob(tex); 
       }
       if (in.nextInt()==6) {
           tex= tex.replaceAll(" ", "");
           Eve(tex);
       }
       else {
      
       break;
       }
case 7:
        new Menu();

    default:
    System.err.println ( "Unrecognized option" );
    break;
}

最佳答案

这是一个使用正则表达式和replaceAll(...) 的完整示例。另外,我更新了您的代码以使用 containsKey(c),而不是获取并检查获取的值是否为 null。这样比较优雅一点。

package eu.webfarmr;

import java.util.HashMap;
import java.util.Map.Entry;

public class LetterFrequency {
    public static void main(String[] args) {
        letterFreq("Some Example 38 sdf %");
    }

    public static void letterFreq(String t) {
        t = t.replaceAll("[^a-zA-Z]", "");
        HashMap<Character, Double> map = new HashMap<Character, Double>();
        for (int i = 0; i < t.length(); i++) {
            char c = t.charAt(i);
            if (map.containsKey(c)) {
                Double d = map.get(c);
                d++;
                map.put(c, d);
            } else {
                map.put(c, 1.0);
            }
        }
        for (Entry<Character, Double> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ":" + (entry.getValue() / t.length()));
        }
    }
}

从 Java 8 开始,实际上有一个简洁的映射函数,您可以使用它来进一步压缩代码:map.merge(c, 1.0, Double::sum);。请参阅下面的片段。本质上,它的作用是如果不存在值,则将值设置为 1,否则递增。

public static void letterFreq(String t) {
    t = t.replaceAll("[^a-zA-Z]", "");
    HashMap<Character, Double> map = new HashMap<Character, Double>();
    for (int i = 0; i < t.length(); i++) {
        char c = t.charAt(i);
        map.merge(c, 1.0, Double::sum);
    }
}

关于java - HashMap 以小数形式打印字母频率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66362011/

相关文章:

java - map 需要过滤没有 tmst 值

c++ - 如何在 unordered_map 中设置值并确定是否添加了新键

java - eofException 与 objectstream 和 hashmap

java - Java 是否有通用的相等性测试也能处理空值?

c# - 我可以使用 foreach 和初始声明 reshape 该代码吗

c++ - BOOST_FOREACH 宏强制方法脱离 Visual Studio 命名空间

c# - MVC 中 javascript 中的嵌套 foreach

java - Java 是运行每个条件运算符还是在 If 语句中短路?

java - 无法实现 OnCheckedChangeListener?

java - 如何在java程序中转换sikuli脚本