统计文本中各个字符出现的次数

本文探讨了基于Huffman编码实现文本数据压缩的过程。重点介绍如何统计文本中各字符出现频率,为后续编码做准备。针对现有程序只能正确统计首个字符频率的问题,分析并寻找解决方案。
基于huffman编码的文本数据压缩中的第一个阶段需要统计一个文本文件中的各个字符出现的次数,以作为字符的权值进行编码
在统计的时候我用一个结构体数组来存储文本中出现的各个字符及其出现的次数
定义如下 struct ChrCount                         
{
char chr;
int count;
} CharCount[128];
下面是我写得程序
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
FILE *fp;
        int j=0;
int i;
struct ChrCount                //存储文件中的各个字符及其个数         
{
char chr;
int count;
} CharCount[128];
char c;
for( i=0;i <128;i++)
{
CharCount[i].count=0;
}
if((fp=fopen("data.txt","a+"))==NULL)
{
printf("can't open file data.txt/n");
exit(1);
}
c=fgetc(fp);
putchar(c);
CharCount[0].chr=c;
CharCount[0].count=1;
j++;
while((c=fgetc(fp))!=EOF)
{
putchar(c);
for( i=0;i <j;i++)
{
if(c==CharCount[i].chr)
{
CharCount[i].count++;
}
else
{
CharCount[j].chr=c;
CharCount[j].count++;
j++;
}
break;
}
}
fclose(fp);
printf("/n");
for( i=0;i <j;i++)
{
printf("%c: ",CharCount[i].chr);
printf("%d/n",CharCount[i].count);
}

}

这个程序的问题在于只能正确统计文本中第一个字符出现的次数,后面的字符出现一次纪录一次,重复纪录
请问是哪个地方出了问题?
<think>好的,我现在需要帮用户解决如何用Java编写程序统计文本文件中每个单词出现次数的问题。首先,我得理清楚用户的需求。用户提到参考了两个引用,一个是Java读取英文文档统计单词次数,另一个是MapReduce的wordcount程序。用户可能希望用基础Java实现类似功能,不需要用到MapReduce框架,但可能需要了解基础思路。 首先,我应该考虑基本的Java I/O操作,读取文件内容。然后,处理文本,比如分割单词,可能需要用正则表达式或者字符串分割方法。接着,统计每个单词的出现次数,通常用HashMap来存储键值对,单词作为键,次数作为值。最后,输出结果。可能还要考虑大小写问题,比如是否区分大小写,是否需要将单词转为小写统一处理。此外,标点符号的处理,比如去掉逗号、句号等。 用户提供的示例中,引用[1]使用了BufferedReader读取文件,逐行处理,用split分割单词,然后存入HashMap。引用[2]是MapReduce的例子,但用户现在只需要Java基础实现。我需要确保代码的每一步都解释清楚,比如文件读取、分割单词、统计次数、遍历输出。 可能的步骤: 1. 使用BufferedReader读取文本文件。 2. 逐行读取,用正则表达式分割成单词,可能用split("\\W+")来分割非单词字符。 3. 将单词转为小写,避免大小写不同造成的重复统计。 4. 使用HashMap统计每个单词的出现次数,存在则加1,否则置1。 5. 遍历HashMap,输出结果。 需要注意的细节: - 文件路径是否正确,异常处理,比如文件不存在的情况。 - 正则表达式的选择,确保正确分割单词。 - 处理空字符串,避免统计到空词。 - 输出结果的排序,是否需要按字母顺序排序,引用[2]提到按字母顺序排序,所以可能需要将HashMap的键存入List,排序后再输出。 代码结构大致如下: - main方法里处理文件读取,调用统计方法。 - 统计方法接收文件路径,返回HashMap。 - 处理每行,分割单词,更新HashMap。 - 最后将entry存入List,排序,然后输出。 可能的问题点: - 分割单词的正则表达式是否正确,比如split("[^a-zA-Z]+")可能更合适。 - 是否考虑单词带有连字符或撇号,如don't,但用户需求可能只需简单处理。 - 异常处理需要try-catch块,捕获IOException。 现在,按照用户给的示例,需要生成相关问题。可能的疑问包括如何处理大小写,如何优化性能,如何处理大文件,或者如何扩展功能,比如统计总单词数,或者按频率排序等。</think>### 如何用Java统计文本中单词出现次数? 以下是分步实现方法: #### 1. 文件读取与内容提取 ```java import java.io.BufferedReader; import java.io.FileReader; import java.util.*; public class WordCounter { public static void main(String[] args) { Map<String, Integer> wordCounts = countWords("english.txt"); printSortedResults(wordCounts); } // 统计核心方法 public static Map<String, Integer> countWords(String filename) { Map<String, Integer> counter = new HashMap<>(); try (BufferedReader br = new BufferedReader(new FileReader(filename))) { String line; while ((line = br.readLine()) != null) { processLine(line, counter); } } catch (Exception e) { e.printStackTrace(); } return counter; } ``` #### 2. 单词分割与统计 ```java private static void processLine(String line, Map<String, Integer> counter) { // 使用正则表达式分割非字母字符 String[] words = line.split("[^a-zA-Z]+"); for (String word : words) { if (!word.isEmpty()) { String key = word.toLowerCase(); counter.put(key, counter.getOrDefault(key, 0) + 1); } } } ``` #### 3. 结果排序与输出 ```java private static void printSortedResults(Map<String, Integer> map) { List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet()); Collections.sort(entries, Map.Entry.comparingByKey()); // 按字母顺序排序[^2] System.out.println("总计单词种类:" + entries.size()); for (Map.Entry<String, Integer> entry : entries) { System.out.println(entry.getKey() + ": " + entry.getValue()); } } } ``` #### 关键实现说明: - **正则分割**:`split("[^a-zA-Z]+")` 过滤所有非字母字符,保留纯单词 - **大小写统一**:`toLowerCase()` 保证"Apple"和"apple"视为同一单词 - **高效统计**:`getOrDefault()` 方法实现快速计数 - **排序输出**:通过`ArrayList`和`Collections.sort`实现字典序排列[^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值