统计文本中各单词出现的频率(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



(二)性能测试



八、软件维护

本次的为个人项目,未发布,暂时不存在维护问题。





posted @ 2014-10-19 16:57  Val1ant  阅读(1002)  评论(0编辑  收藏  举报