【问题标题】:HashMap to print out letter frequency in decimals?HashMap以小数形式打印字母频率?
【发布时间】:2021-05-27 10:17:44
【问题描述】:

我有这个代码:

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 这应该意味着 .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(" ","")?
  • @DavidBrossard 我做了 t.replaceAll(" ","");在哈希图开始之前,它仍然没有工作
  • 你知道你必须把它分配回t。 replaceAll() 不会更改调用它的字符串的值。 javatpoint.com/java-string-replaceall
  • 可能不是空格,而是回车或换行符或其他不可打印的字符。你可以试试t = t.replaceAll("\\W", "")

标签: java foreach hashmap


【解决方案1】:

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

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 函数,您可以使用它来进一步压缩代码:map.merge(c, 1.0, Double::sum);。请参阅下面的 sn-p。本质上,它的作用是在不存在值时将值设置为 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);
    }
}

【讨论】:

  • 非常感谢您对我可以浓缩的更好方式的帮助和见解。我把它放进去,它工作得很好。花了一个半小时试图让空间计数消失
【解决方案2】:

我无法重现您看到的内容。我复制了你的代码并做了一个测试:

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 (Map.Entry<Character, Double> entry : map.entrySet()) {
        System.out.println(entry.getKey() + ":" + (entry.getValue() / t.length()));
    }
    return t;
}
@Test public void testLetterFreq() {
    LetterFreq("thisisjulz");
}

我生产:

s:0.2
t:0.1
u:0.1
h:0.1
i:0.2
j:0.1
z:0.1
l:0.1

...这对我来说似乎是正确的

【讨论】:

  • 似乎哈希图不是问题,然后我将发布我如何将“String t”获取到 letterfreq,也许这将有助于解决我认为无关紧要但按原样运行的问题工作正常。
猜你喜欢
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多