一、实验题目
- 实验题目:
建立一个文本文件,统计给定单词在文本文件中出现的总次数及位置 - 实验要求
-
文本文件中每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写,统计给定单词在文本文件中出现的总次数,检索输出的某个单词出现在文本中的行号、在该行中出现的位置。
-
设计数据量大的文本,进行子串的查询处理,分析算法运行的时间效率,对所有输出的匹配位置结果进行验证,以证明算法设计和实现的正确性。
-
用朴素模式匹配算法或KMP算法实现字符串定位;
-
可正确读取,保存文本;
二、编程语言以及开发环境
1. 编程语言:
选择Java,因为在上学期 project 01中对Java进行了一次提高,现在习惯用Java来编写
2. 开发环境:
选择IntelliJ IDEA,使用起来更加方便
三、源代码
1.服务类
package dataSearch;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class serves {
//存储读取文本文档后的信息
String textDocument;
//将要查找的单词
String willSearchWord;
Scanner scanner =new Scanner(System.in);
/**
*读文本文档
*/
public void readText(){
//防止异常
try{
StringBuffer buffer = new StringBuffer();
BufferedReader bufferedReader= new BufferedReader(new FileReader("D:\\旧桌面\\数据结构项目三\\项目三.txt"));
String readLine = null;
while( (readLine = bufferedReader.readLine()) != null ){
buffer.append(readLine.trim());
}
//转换为字符串型
textDocument = buffer.toString();
}catch (IOException e){
System.out.println(e.getMessage());
}
}
/**
*
*/
public void begin(){
//寻找到的单词的计数器
int count;
//调用读文件
readText();
System.out.println("请输入要查询的单词");
willSearchWord = scanner.next();
//调用KMP方法
count = KMP(textDocument, willSearchWord);
if(count==0){
System.out.println("未找到单词");
}
else{
System.out.println("一共找到"+count+"个");
}
}
/**
* KMP算法
* @param textDocument
* @param willSearchWord
* @return
*/
public int KMP(String textDocument, String willSearchWord) {
int num = 0;
int i = 0;
while( i< textDocument.length())
{
//字符型数组
char[] charTextDocument = textDocument.toCharArray();
char[] charWillSearchWord = willSearchWord.toCharArray();
int j = 0; // 模式串的位置
int[] next = getNext(willSearchWord);
while (i < charTextDocument.length && j < charWillSearchWord.length) {
if (j == -1 || charTextDocument[i] == charWillSearchWord[j]) { // 当j为-1时,要移动的是i,当然j也要归0
i++;
j++;
} else {
j = next[j]; // j回到指定位置
}
}
if (j == charWillSearchWord.length) {
site(i-j,willSearchWord);
num++;
}
}
return num;
}
/**
*得到next数组
* @param willSearchWord
* @return
*/
public static int[] getNext(String willSearchWord) {
char[] charwillSearchWord = willSearchWord.toCharArray();
int[] next = new int[charwillSearchWord.length];
next[0] = -1;
int j = 0;
int k = -1;
while (j < charwillSearchWord.length - 1) {
if (k == -1 || charwillSearchWord[j] == charwillSearchWord[k]) {
if (charwillSearchWord[++j] == charwillSearchWord[++k]) { // 当两个字符相等时要跳过
next[j] = next[k];
} else {
next[j] = k;
}
} else {
k = next[k];
}
}
return next;
}
/**
*得到位置
* @param firstLength
* @param word
*/
public void site(int firstLength, String word){
int allLength = firstLength+word.length()-1;
System.out.println("单词位置:"+firstLength+"~"+allLength);
}
}
2. main类
package dataSearch;
public class main {
public static void main(String[]args){
serves input=new serves();
input.begin();
}
}
四、运行结果
1. 初始界面:
2. 查询界面:
五、实验小结
- 在本次实验中,对KMP算法的应用中做的不到位,虽然预习的时候,理解了KMP算法的思想,但是在代码中做不到表达出来,最终还是借鉴了别人的一部分代码,才完成项目。
- 在完成之外,也尝试使用了暴力匹配算法,这个算法比较容易理解以及使用,对于KMP算法,会多加练习,达到能使用的程度。
今日喜欢的句子:
你有时会站在自己的那座孤独山丘,以为风尘滚滚也会比别人高瞻远瞩。