统计文本中各单词出现的频率(JavaWeb)
统计文本单词频率
一、问题定义:
这次的工程任务为软件工程课程作业,旨在使用某种编程语言,完成统计文本文件中各单词出现的频率,并将前10的单词打印出来。问题的规模限于几个页面与后台的简单的数据交互。
二、可行性分析
该项目是基于Java语言,而java封装了大量各种处理方法,对文本文件,输入输出流、字符串处理等方面有着很大的优势,这样能够使具体处理函数透明化,故选择java语言。而其中字符串的split方法为该项目中处理字符串的主要函数,因此使得项目中关键的较长字符串处理成为可能,也是项目的规模得以较大的简化。
三、需求分析
该项目中为解决用户统计文本文件中单词的需求,设计了一个起始页面,提示用户上传需要统计分析的文本文件,这是系统会取得用户上传的文本文件,将其保存至服务器端,同时启动后台程序,读取上传文件,进行分析,得到结果,返回结果去前台页面,将处理后结果以表格形式展现出来。
四、总体设计
该项目为提高交互友好性,选择了JavaWeb形式,以常见的网页为程序起始页,使后台处理完全透明化。同时由于JavaWeb多见于大型项目,本次的项目也有较高的并发访问行与稳定性,并且能够长期同时提高服务。同时采用MVC的设计模式,使得控制层与业务逻辑层、视图层独立性提高,值得系统的模块化较高,有较好的后期维护性。
五、详细设计
该部分主要利用统一建模语言UML,建立该项目的模型与结构流程,确定每一个模块需要的算法及数据结构。
六、编码与单元测试
(一)Java后台代码部分
1、实体类mode.java
package com.xzp.unity; /** * 实体类 * @author Xzp * */ public class Model { private String[] s; //字符串数组 private int[] n; //整形数组 //get set方法 public String[] getS() { return s; } public void setS(String[] s) { this.s = s; } public int[] getN() { return n; } public void setN(int[] n) { this.n = n; } }2、工具类 Tools.java
package com.xzp.util; import java.util.Scanner; import com.xzp.unity.Model; /** * @author Xzp * */ public class Tools { /** * * @param s 目标字符串数组 * @param str 匹配字符串 * @return 匹配结果 字符串第一次出现的位置 */ public int firstAppear(String[] s,String str) { for (int i = 0; i < s.length; i++) { // System.out.println("s1"+s[i]); if (s[i].equals(str)) { // System.out.println(s[i]+"="+str); return i; } } return -1; } /** * 对Model中的字符串数组与整形数组排序 * @param model */ public void sort(Model model) { int[] n = model.getN(); String[] s = model.getS(); int flag = 0; String s1 = null; //冒泡排序 for (int i = 0; i < n.length; i++) { for (int j = i; j < n.length; j++) { if (n[j]>n[i]) { //交换数组 flag = n[j]; n[j] = n[i]; n[i] = flag; //交换字符串 s1=s[i]; s[i] = s[j]; s[j] = s1; } } } } /** * 输入函数,作测试用 * @return */ public String input() { System.out.println("----------------------------"); System.out.println("请输入:"); String text; Scanner scan = new Scanner(System.in); text = scan.nextLine(); //逐行读取 scan.close(); return text; } /** * 处理两个数组字符串次数与字符串对应关心操作 * @param s1 * @param model */ public void handle(String[] s1,Model model) { int m = 0; Tools t = new Tools(); for (int i = 0; i < s1.length; i++) { if ((t.firstAppear(s1, s1[i]))==i) { model.getS()[m] = s1[i]; model.getN()[m] = 1; m++; } else{ model.getN()[t.firstAppear(s1, s1[i])] = model.getN()[t.firstAppear(s1, s1[i])]+1; } } } /** * 后台显示方法 * @param model */ public void display(Model model) { // for (int j = 0; j < 10; j++) { if (model.getS()[j]!=null) { System.out.print(model.getS()[j]); System.out.println("----次数"+model.getN()[j]); } } } /** * 执行字符串分隔处理 * @param s传入待处理的字符串 * @return 返回处理后的字符串数组 */ <strong><span style="color:#000099;">public String[] doSplit(String s) { String[] s1; s = s.replaceAll("[\\pP\\p{Punct}]", ""); //替换空格 // s1 = s.split("[\\s\\p{Zs}]+"); // for (String str : s1) { // System.out.println(str); // } // StringBuffer sb = new StringBuffer(); // for (int i = 0; i < s1.length; i++) { // sb.append(s1[i]); // } // s = sb.toString(); s1 = s.split("\\pP+|\\pZ+|\\pS+|\\pN+|\\pC+|\\p{Zs}+"); //按各类字符匹配 return s1; }</span></strong>其中split方法正则表达式匹配说明:点击打开链接
Unicode 编码并不只是为某个字符简单定义了一个编码,而且还将其进行了归类。
\pP 其中的小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。
大写 P 表示 Unicode 字符集七个字符属性之一:标点字符。
其他六个是
L:字母;
M:标记符号(一般不会单独出现);
Z:分隔符(比如空格、换行等);
S:符号(比如数学符号、货币符号等);
N:数字(比如阿拉伯数字、罗马数字等);
C:其他字符
3、控制器层操纵类----Count.java
package com.xzp.biz; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import com.xzp.unity.Model; import com.xzp.util.Tools; public class Count { public Model doCount(String url) throws IOException { String[] s; int[] n; File file = new File(url); Model model = new Model(); Tools tool = new Tools(); FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); StringBuffer sb = new StringBuffer(); String data = new String(); data = br.readLine(); while (data != null) { sb.append(data); data = br.readLine(); } data = sb.toString(); br.close(); fr.close(); s = tool.doSplit(data); n = new int[s.length]; model.setS(s); model.setN(n); tool.handle(s, model); tool.sort(model); return model; }
(一)JSP前台代码
1、主页面index.jsp
<%@page import="java.io.*"%> <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>文件读取</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <link rel="stylesheet" type="text/css" href="CSS/styles.css"> </head> <body> <h1>统计分析单词频率</h1> <hr style="border:1 dashed #987cb9" width="100%" color=#6666CC SIZE=1> <form action="Page/jspSmartUpload.jsp" method="post" enctype="multipart/form-data"> <!-- 使用绝对路径--> 请选择文件: <input type="file" name="upfile" value="浏览"/> <input type="submit" name="upload" value="上传"/> </form> </body> </html>
2、处理文件上传及显示结果界面-----jspSmartUpload.jsp、(使用jspSmartUpload处理文件上传)
<%@page import="sun.swing.text.CountingPrintable"%> <%@page import="com.xzp.util.Tools"%> <%@page import="com.xzp.unity.Model"%> <%@page import="com.jspsmart.upload.File"%> <%@page import="com.xzp.biz.Count"%> <%@page import="com.jspsmart.upload.SmartUpload"%> <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'jspSmartUpload.jsp' starting page</title> <script type="text/javascript" src="JS/SaveTable.js" charset="utf-8"></script> <!-- 注意此处的路径问题 跳转之后文件路径未改变,仍未index.jsp的目录 --> <script type="text/javascript"> </script> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <h1>统计结果:</h1> <body> <% //完成上传 request.setCharacterEncoding("utf-8"); SmartUpload su = new SmartUpload(); //新建一个smartUpload对象 su.initialize(pageContext); //上传初始化 pageContext为JSP内置对象 su.setAllowedFilesList("txt,doc,docx"); //设定上传的文件格式 su.upload(); //上传 su.save("upload",SmartUpload.SAVE_VIRTUAL); //保存到指定文件夹 %> <% //统计操作 Count count = new Count(); String url = su.getFiles().getFile(0).getFileName(); // String path = request.getRealPath("/"); path = request.getSession().getServletContext().getRealPath("/"); // out.println("path"+path+"<br/>"); url = path + "upload\\"+url; // out.println(url); Model model = new Model(); Tools tool = new Tools(); model = count.doCount(url); /* for(int i = 0;i<model.getS().length;i++){ if(model.getS()[i]!=null){ out.println(model.getS()[i]); out.println("次数:"+model.getN()[i]+"<br/>"); } } */ %> <!-- 展示结果 --> <table id="mytable" style="text-align: center;width: 60%;border: solid; border-color: #BDB76B;" align="center" border="1"> <thead> <tr style="height: 40px;"> <td><font size="8"><b>序号</b></font></td> <td><font size="8"><b>单词</b></font></td> <td><font size="8"><b>次数</b></font></td> </tr> </thead> <tbody> <% for(int i = 0,j = 0;i<model.getS().length;i++){ <strong><span style="color:#33cc00;"> </span><span style="color:#6633ff;"> if (model.getS()[i].equals("of") <strong><span style="color:#cc33cc;">|| model.getS()[i].matches("[A-Za-z]") //去除单个单词 //去除常见介词 || model.getS()[i].equals("in") || model.getS()[i].equals("the") || model.getS()[i].equals("at") || model.getS()[i].equals("on") || model.getS()[i].equals("by") || model.getS()[i].equals("to") || model.getS()[i].equals("he") || model.getS()[i].equals("He") || model.getS()[i].equals("She") || model.getS()[i].equals("she") || model.getS()[i].equals("it") || model.getS()[i].equals("It")</span></strong> ){</span><span style="color:#333300;"> continue;</span></strong> }else{ if (model.getS()[i] != null) { j++; if(j>10)break; %> <tr style="height: 35px;"> <td><%=j %></td> <td><%=model.getS()[i] %></td> <td><%=model.getN()[i] %></td> </tr> <% } } } %> </tbody> </table> <button onclick="test()">保存3</button> </body> </html>七、综合测试
(一)运行界面及结果
1、index.jsp界面
2、结果界面jspSamrtUpload.jsp
(二)性能测试
八、软件维护
本次的为个人项目,未发布,暂时不存在维护问题。