HashMap以小数形式打印出字母频率?
HashMap to print out letter frequency in decimals?
我有这个代码:
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...
一些变体,无论我有一个没有字母的空白 space 但它给出了一个我不明白为什么的小数值?
更新:
我假设这与字符串中的 spaces 有关,但是当我像 thisisjulz
这样一起输入文本时,我们可以在这里看到字母 s 出现了 2/10应该是 .2,但我的代码甚至在我没有像上面引用的示例中那样放置的代码中注册了 spaces,并将其计为 1 个字符 space。有什么方法可以实现定界符或其他东西来确保它只计算有值的字符吗?
Updatev2:这是我从中获取“string 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;
}
我无法重现您所看到的。我复制了你的代码并做了测试:
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
...这对我来说似乎是正确的
这是一个使用正则表达式和 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> 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);
}
}
我有这个代码:
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...
一些变体,无论我有一个没有字母的空白 space 但它给出了一个我不明白为什么的小数值?
更新:
我假设这与字符串中的 spaces 有关,但是当我像 thisisjulz
这样一起输入文本时,我们可以在这里看到字母 s 出现了 2/10应该是 .2,但我的代码甚至在我没有像上面引用的示例中那样放置的代码中注册了 spaces,并将其计为 1 个字符 space。有什么方法可以实现定界符或其他东西来确保它只计算有值的字符吗?
Updatev2:这是我从中获取“string 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;
}
我无法重现您所看到的。我复制了你的代码并做了测试:
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
...这对我来说似乎是正确的
这是一个使用正则表达式和 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> 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);
}
}