文本文件单词统计

1. 问题描述

有如下的英文文本文档:(文件名是:History.txt)

History

Taiyuan University of Technology (TYUT) can trace its origin to the Western Learning School, Shanxi Grand Academy, established in 1902 as one of the earliest three universities in China’s higher education history. Having developed through many different stages, TYUT has successively used many names: Engineering Department of Shanxi Grand University; School of Engineering, Shanxi University; becoming independent in 1953, Taiyuan Institute of Technology was under direct administration of Ministry of Higher Eeducation; handed back to Shanxi Province in 1962; Taiyuan University of Technology in 1984; merging Shanxi Institute of Mining in 1997, which was founded in 1958 by Ministry of Coal, then new Taiyuan University of Technology; included in “211” Project the same year, a national higher education promotion program for the 21st century.

设计语言程序,统计在这样的英文文本文件中,出现了多少个单词(不区分大小写),每个单词出现了几次。连续的英文字符都认为是单词(不包括数字),单词之间用空格或标点符号分隔。

注意:

i) 输入要统计单词的文本文件名,打开相应的文件。文件至少包含50个英文单词(一定出现重复的单词,且一定包含数字)

ii) 文档不规范,单词之间可能不只有一个空格,并且有加引号的一些单词“jiaozi”加引号的单词算单词,但数字不算单词

iii) 逐行扫描文本文件,计算文档中单词总数,及各个单词出现的频次,并且按照单词首字母abcd…… 的顺序排列,显示并生成soft.txt文件

iv) 查询任意给出的单词是否存在,如果不存在,在屏幕上输出“查无此词!”;如果存在,显示单词出现的总次数,并且详细列出其出现的位置。

例如:

请您输入待查询的词:of

单词 of 共出现了2次;

第1次出现在第1行,第5个位置;

第2次出现在第3行,第1个位置。

请您输入待查询的词:

2. 问题分析

要统计英文文本文件中出现了哪些单词,就要从文件中读取字符,读取出来的连续英文字符认为是一个单词,遇空格或标点符号单词结束。

使用线性表记录单词以及每个单词出现的次数。线性表中的单词按字典顺序存储。

线性表的顺序存储结构如下:(必须使用如下定义的存储结构,否则无效)

#define LIST_INIT_SIZE 100    //线性表存储空间的初始分配量

#define LISTINCREMENT 10      //线性表存储空间的分配增量

typedef struct{

    char word[21]             //存储单词,不超过20个字符

    int count;                //单词出现的次数

} ElemType;                   //顺序表元素类型

typedef struct{

    ElemType *elem;           //存储空间基址

    int length;               //当前长度

int listsize;             //当前分配的存储容量

} Seqlist;                    //顺序表类型

3. 功能实现

  1. 程序应先询问用户的 ID号(ID 号包括两个大写字母和4 位数字)

例如: 请输入用户 ID 号:AB1234

(2)程序应对输入的 ID 号验证,符合 ID 号要求的格式,然后程序提示四种选择: ①建立文件 ②单词统计 ③单词查询及定位 ④退出

(3)初始化顺序表;

(4)从文本文件中读取字符,直到文件结束。具体描述如下:

while (读文件没有结束)

{

       过滤单词前的非字母字符;

       读取一个单词,以字符串形式存储在一个字符数组中;

       在线性表中查找该单词,若找到,单词的出现次数加1,否则返回其插入位置;

       上一步中,若没找到,则进行插入操作;

       处理下一个单词。

}

  1. 关闭文件,输出统计结果。

4. 源程序清单

package demo;



import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.Objects;

import java.util.Scanner;

import java.util.TreeMap;



public class WordStatistics {

private static Scanner scanner = new Scanner(System.in);



private static StringBuilder builder = new StringBuilder();



private static String[] words = null;



private static List<String> list = new ArrayList<>();



private static Map<String, Integer> wordsMap = new TreeMap<>();



public static void main(String[] args) throws Exception {

run();

}



private static void run() {

if (checkUser()) {

while (true) {

try {

int selectId = remindFourSelect();

responseUserById(selectId);

continue;

} catch (Exception e) {

errorLog(e.getMessage());

break;

}

}

} else {

errorLog("id is not ok");

}

}



private static void log(String log) {

System.out.println(log);

}



private static void errorLog(String log) {

System.err.println(log);

}



private static boolean checkUser() {

log("请输入用户ID号:");

String id = scanner.nextLine();

return idIsOk(id);

}



private static boolean idIsOk(String id) {

return id.matches("[A-Z]{2}[0-9]{4}");

}



// 提示四种选择

private static int remindFourSelect() {

log("\n*****************************");

log("(1)  建立文件");

log("(2)  单词统计");

log("(3)  单词查询及定位");

log("(4)  退出");

log("*****************************\n");

return Integer.parseInt(scanner.nextLine());

}



private static String filePath = null;



// 根据选择的id做出响应

private static void responseUserById(int id) throws IOException {

switch (id) {

case 1:

filePath = makeFile(); // 建立文件

StringBuilder fileInfo = getToFileInfo(); // 获得键盘录入文件内容

toFile(fileInfo, filePath); // 写入文件

break;

case 2:

wordCensus(); // 单词统计

break;

case 3:

WordQueryAndLocation(); // 单词查询及定位

break;

case 4:

exit(); // 退出

break;

default:

throw new RuntimeException("没有对应的选项");

}

}



private static String makeFile() throws IOException {

log("请输入文件名 eg: (index.txt)");

File file = new File("c:\\" + scanner.nextLine());

if (file.createNewFile()) {

errorLog("新建成功, 文件路径:" + file.getAbsolutePath());

} else {

errorLog("创建文件失败, 文件已存在");

}

return file.getAbsolutePath();

}



private static StringBuilder getToFileInfo() {

log("请输入要写入文件的内容,(回车+@vivi结束输入)");

String info = "";

StringBuilder sb = new StringBuilder();

while (!"@vivi".equalsIgnoreCase(info)) {

info = scanner.nextLine();

sb.append(info + "\n");

}

return sb;

}



// 单词统计

private static void wordCensus() throws IOException {

readFile();

spliceWords();

countWords();

printCountWordsInfoAndToFile();

}



private static String readFile() throws IOException {

String path = "";

if (Objects.isNull(filePath)) {

// 说明没有执行过创建文件的方法

log("请输入待读取文件的绝对路径:");

path = scanner.nextLine();

} else {

path = filePath;

}

BufferedReader reader = new BufferedReader(new FileReader(path));

String line = null;

while ((line = reader.readLine()) != null) {

builder.append(line + "\n");

}

reader.close();

return path;

}



private static void spliceWords() {

words = builder.toString().split("\\s+|\\n+|\\t+|\\r+|\"");

Arrays.stream(words).forEach(word -> {

if (word.matches("^[A-Za-z]+$")) {

list.add(word);

}

});

}



// 统计单词的个数

private static void countWords() {

list.forEach(word -> {

if (wordsMap.containsKey(word)) {

wordsMap.put(word, wordsMap.get(word) + 1);

} else {

wordsMap.put(word, 1);

}

});

}



// 打印统计的单词信息并写入文件

private static void printCountWordsInfoAndToFile() {

StringBuilder sb = new StringBuilder();

wordsMap.keySet().forEach(word -> {

sb.append("单词:" + word + " \t共出现了:" 

+ wordsMap.get(word) + " 次\n");

});

sb.append("文档中共有:" + list.size() + " 个单词");

log(sb.toString());

toFile(sb, "d:\\soft.txt");

}



private static void toFile(StringBuilder sb, String filePath) {

try (BufferedWriter writer =

new BufferedWriter(new FileWriter(filePath))) {

writer.write(sb.toString());

errorLog("文件写入成功:文件路径:" + filePath + "\n");

} catch (IOException e) {

e.printStackTrace();

}

}



// 单词查询及定位

private static void WordQueryAndLocation() throws IOException {

String filePath = readFile();

spliceWords();

String word = readWord();

if (isHasWord(word)) {

// 文件中存在该单词

queryAndLocation(word, filePath);

return;

}

noWord();

}



private static String readWord() {

log("请输入要查询的单词");

return scanner.nextLine();

}



private static boolean isHasWord(String word) {

return list.contains(word);

}



// 查询并定位单词

private static void queryAndLocation(String word, String filePath)

  throws IOException {

BufferedReader reader = new BufferedReader(new FileReader(filePath));

int lineNum = 0; // 行号

int count = 1; // 次数

int location = 0; // 位置索引

String line = null; // 每行的字符串

while ((line = reader.readLine()) != null) {

lineNum++;

int preLocation = 0; // 上一次的位置

while ((location = line.indexOf(word)) != -1) {

log("第 " + (count++) + " 次,出现在第 "

 + lineNum + " 行,第 " + (preLocation + location + 1) + " 个位置");

preLocation += location + word.length();

line = line.substring(location + word.length());

}

}

log("单词:" + word + " 共出现了:" + (--count) + " 次");

reader.close();

}



private static void noWord() {

errorLog("查无此词");

}



private static void exit() {

throw new RuntimeException("欢迎再次使用");

}



}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值