Java 以百分比表示的单词频率
我必须制作一个程序,从linkedlist中计算单词频率,并输出如下结果: 单词、出现次数、频率(百分比)Java 以百分比表示的单词频率,java,Java,我必须制作一个程序,从linkedlist中计算单词频率,并输出如下结果: 单词、出现次数、频率(百分比) import java.io.File; import java.io.FileNotFoundException; import java.util.*; public class Link { public static void main(String args[]) { long start = System.currentTimeMillis();
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class Link {
public static void main(String args[]) {
long start = System.currentTimeMillis();
LinkedList<String> list = new LinkedList<String>();
File file = new File("words.txt");
try {
Scanner sc = new Scanner(file);
String words;
while (sc.hasNext()) {
words = sc.next();
words = words.replaceAll("[^a-zA-Z0-9]", "");
words = words.toLowerCase();
words = words.trim();
list.add(words);
}
sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Map<String, Integer> frequency = new TreeMap<String, Integer>();
for (String count : list) {
if (frequency.containsKey(count)) {
frequency.put(count, frequency.get(count) + 1);
} else {
frequency.put(count, 1);
}
}
System.out.println(frequency);
long end = System.currentTimeMillis();
System.out.println("\n" + "Duration: " + (end - start) + " ms");
}
}
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.util.*;
公共类链接{
公共静态void main(字符串参数[]){
长启动=System.currentTimeMillis();
LinkedList=新建LinkedList();
文件=新文件(“words.txt”);
试一试{
扫描仪sc=新扫描仪(文件);
字符串;
while(sc.hasNext()){
words=sc.next();
words=words.replaceAll(“[^a-zA-Z0-9]”,“”);
words=words.toLowerCase();
words=words.trim();
列表。添加(文字);
}
sc.close();
}catch(filenotfounde异常){
e、 printStackTrace();
}
映射频率=新树映射();
用于(字符串计数:列表){
if(频率容器(计数)){
frequency.put(计数,frequency.get(计数)+1);
}否则{
频率。put(计数,1);
}
}
系统输出打印项次(频率);
long end=System.currentTimeMillis();
System.out.println(“\n”+”持续时间:“+(结束-开始)+”毫秒”);
}
}
输出:{a=1,ab=3,abbc=1,asd=2,xyz=1}
我不知道的是如何以百分比表示频率,并忽略小于2个字符的单词。例如,应忽略“a=1”
提前感谢。在添加到映射步骤时忽略大小小于2的字符串,并维护用于计算百分比的合法单词计数器
int legalWords = 0;
for (String count: list) {
if (count.size() >= 2) {
if (frequency.containsKey(count)) {
frequency.put(count, frequency.get(count) + 1);
} else {
frequency.put(count, 1);
}
legalWords++;
}
}
for (Map.Entry < String, String > entry: map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue() + " " + (entry.getValue() / (double) legalWords) * 100.0 + "%");
}
int-legalWords=0;
用于(字符串计数:列表){
如果(count.size()>=2){
if(频率容器(计数)){
frequency.put(计数,frequency.get(计数)+1);
}否则{
频率。put(计数,1);
}
legalWords++;
}
}
对于(Map.EntryEntry:Map.entrySet()){
System.out.println(entry.getKey()+“”+entry.getValue()+“”+(entry.getValue()/(双)法律词汇)*100.0+“%”;
}
在添加到映射步骤时忽略大小小于2的字符串,并维护用于计算百分比的合法字词计数器
int legalWords = 0;
for (String count: list) {
if (count.size() >= 2) {
if (frequency.containsKey(count)) {
frequency.put(count, frequency.get(count) + 1);
} else {
frequency.put(count, 1);
}
legalWords++;
}
}
for (Map.Entry < String, String > entry: map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue() + " " + (entry.getValue() / (double) legalWords) * 100.0 + "%");
}
int-legalWords=0;
用于(字符串计数:列表){
如果(count.size()>=2){
if(频率容器(计数)){
frequency.put(计数,frequency.get(计数)+1);
}否则{
频率。put(计数,1);
}
legalWords++;
}
}
对于(Map.EntryEntry:Map.entrySet()){
System.out.println(entry.getKey()+“”+entry.getValue()+“”+(entry.getValue()/(双)法律词汇)*100.0+“%”;
}
首先,引入一个double
变量来跟踪事件总数。例如
double total = 0;
接下来是用length()<2
过滤掉任何字符串。在将它们添加到LinkedList
之前,您已经可以这样做了
while (sc.hasNext()) {
words = sc.next();
words = words.replaceAll("[^a-zA-Z0-9]", "");
words = words.toLowerCase();
words = words.trim();
if (words.length() >= 2) list.add(words); //Filter out strings < 2 chars
}
然后我们可以使用System.out.printf()
很好地打印出来
for (Map.Entry<String, Integer> entry: frequency.entrySet()) {
System.out.printf("String: %s \t Occurences: %d \t Percentage: %.2f%%%n", entry.getKey(), entry.getValue(), entry.getValue()/total*100);
}
首先,引入一个double
变量来跟踪事件总数。例如
double total = 0;
接下来是用length()<2
过滤掉任何字符串。在将它们添加到LinkedList
之前,您已经可以这样做了
while (sc.hasNext()) {
words = sc.next();
words = words.replaceAll("[^a-zA-Z0-9]", "");
words = words.toLowerCase();
words = words.trim();
if (words.length() >= 2) list.add(words); //Filter out strings < 2 chars
}
然后我们可以使用System.out.printf()
很好地打印出来
for (Map.Entry<String, Integer> entry: frequency.entrySet()) {
System.out.printf("String: %s \t Occurences: %d \t Percentage: %.2f%%%n", entry.getKey(), entry.getValue(), entry.getValue()/total*100);
}
注意:由于OP问题没有为我们提供详细信息,让我们假设我们将计算一个字符的单词,但我们不会输出它们
将逻辑与主类分开:
计算单词的频率百分比:
设置单词的统计信息(出现次数+频率):
输出:
注意:由于OP问题没有提供详细信息,让我们假设我们将计算一个字符的单词,但我们不会输出它们
将逻辑与主类分开:
计算单词的频率百分比:
设置单词的统计信息(出现次数+频率):
输出:
注意:虽然您是从Java开始的,但不要将所有代码都塞进主代码中。函数/方法应该做一件事,而不是两件、三件或十件。回答您的问题:您真的需要Stackoverflow向您介绍if/then/else的概念吗?例如:如果(单词少于2个字符),那么不要将其添加到单词列表中?!在频率中,短于2个字符的单词也应该被忽略吗?我的意思是:“aa”应该输出{aa=0.5}或{a=1.0}?短于2个字符的单词不会将它们算作一个单词,或者您会计算它们,但不会将它们放入输出中。?注意:虽然您是从Java开始的,但请尽量不要将所有代码塞进main。函数/方法应该做一件事,而不是两件、三件或十件。回答您的问题:您真的需要Stackoverflow向您介绍if/then/else的概念吗?例如:如果(单词少于2个字符),那么不要将其添加到单词列表中?!在频率中,短于2个字符的单词也应该被忽略吗?我的意思是:“aa”应该输出{aa=0.5}或{a=1.0}?短于2个字符的单词不会算作一个单词,或者你会计算它们,但不会将它们放入输出中。所有这些链接和lambda都会造成一些不愉快的缩进。我发现很难相信这些工具的真正用途是这样的。当组合多个功能时,例如删除重复的单词并循环列表并建立一个单词统计信息的列表时,它似乎有点长@bhspencer也许这可以通过遵循流链和lambdas的一些代码格式标准来改进,但就目前情况而言,我发现它几乎不可读。@bhspencer我明白你的意思,你完全正确。代码必须是可读的,并且对人们来说是显而易见的。那么现在呢(答案编辑)?那就更干净了。谢谢。A
words.stream()
.filter(p -> p.equalsIgnoreCase(word)).count();
frequency = (float) occurrences / words.size() * 100;
List<WordStatistics> wordsStatistics = new LinkedList<WordStatistics>();
words.stream()
.distinct()
.forEach(
word -> wordsStatistics.add(new WordStatistics(word)
.calculateOccurrences(words)
.calculateFrequency(words)));
wordsStatistics
.stream()
.filter(word -> word.getWord().length() > 1)
.forEach(
word -> System.out.printf("Word : %s \t"
+ "Occurences : %d \t"
+ "Frequency : %.2f%% \t\n", word.getWord(),
word.getOccurrences(), word.getFrequency()));
Word : C# Occurences : 2 Frequency : 18.18%
Word : Java Occurences : 4 Frequency : 36.36%
Word : C++ Occurences : 1 Frequency : 9.09%
Word : php Occurences : 1 Frequency : 9.09%