如何解决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 将 i 输入到控制台的值发送给 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) 而不是获取和检查获取的值是否为空。它更优雅一些。
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>();
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
map.merge(c,Double::sum);
}
}
,
我无法重现您所看到的内容。我复制了您的代码并进行了测试:
public String LetterFreq(String t) {
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
...这对我来说似乎是正确的
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。