package String.kmp;
import java.io.*;
import java.util.HashMap;
import java.util.Properties;
import java.util.Scanner;
public class kmp {
private int n=1;
private HashMap hashmap= new HashMap<Integer,Integer>(); //用来存放数据
public int kmp(String stra, String str) {
n=0;
char[] s = stra.toCharArray();
char[] t = str.toCharArray();
int[] next = next(str);
int i = 0;
int j = 0;
while (i <= s.length - 1 && j <= t.length - 1) {
if (j == -1 || s[i] == t[j]) {
i++;
j++;
} else {
j = next[j];
}
}
if (j < t.length) {
return -1;
} else{
hashmap.put(++n,i-t.length);
return i - t.length; // 返回模式串在主串中的头下标
}
}
public void print(){
String s="";
if(n==0){
System.out.println("失配!");
}else{
System.out.println("匹配成功!");
for(int i=1;i<=hashmap.size();i++){
System.out.println("第"+i+"次出现 出现位置为"+hashmap.get(i));
}
}
}
public static int[] next(String str) {
char[] t = str.toCharArray();
int[] next = new int[t.length];
next[0] = -1;
int i = 0;
int j = -1;
while (i < t.length - 1) {
if (j == -1 || t[i] == t[j]) {
i++;
j++;
if (t[i] != t[j]) {
next[i] = j;
} else {
next[i] = next[j];
}
} else {
j = next[j];
}
}
return next;
}
public void printNext(String b){
int[] next = next(b);
System.out.println("依次计算next表的值:");
for (int i : next) {
System.out.print(" "+i);
}
System.out.println(" ");
}
public String writeContent(String a,String b){
String s="";
if(n==0){
System.out.println("失配!");
s+=a+" "+b +" "+" 失配"+"\n";
}else{
System.out.println("匹配成功!");
for(int i=1;i<=hashmap.size();i++){
Object o = hashmap.get(i);
int value= (int) o+1;
s+=a+" "+b +" "+"第"+i+"次出现 出现位置为第"+value+"个位置"+"\n";
}
}
System.out.println(s);
return s;
}
/*
public String readFile(String address) throws IOException {
File file = new File(address);
long length = file.length();
byte[] bytes = new byte[(int)length];
FileInputStream inputStream=null;
try {
inputStream=new FileInputStream(file);
inputStream.read(bytes);
return new String(bytes,"UTF-8");
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
inputStream.close();
}
}
*/
public String readFile(String address) throws IOException {
FileInputStream inputStream = new FileInputStream(address);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String string="";
int readNumber = Integer.parseInt(bufferedReader.readLine());
for(int i=0;i<readNumber;i++){
string+=bufferedReader.readLine()+"-";
}
return string;
}
public String[] ToArray(String string){
String[] strings = string.split("-");
return strings;
}
public void fileWriter(String adress,String content) throws IOException {
FileWriter writer=null;
try {
writer = new FileWriter(adress,true);
writer.write(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
writer.flush();
writer.close();
}
}
public static void main(String[] args) throws IOException {
// String astring="vaethababcdbabcfewbtnababcdbabcababcdbabc";
// String bstring="ababcdbabc";
System.out.println("请输入你想要匹配的文件!");
Scanner scanner = new Scanner(System.in);
String fileAddress = scanner.nextLine();
kmp kmp = new kmp();
String afileConent = kmp.readFile(fileAddress);
System.out.println(afileConent);
String[] aStrings=kmp.ToArray(afileConent);
System.out.println("请输入你想要匹配的模式串所在的文件地址:");
String AddressB = scanner.nextLine();
String bfileContent = kmp.readFile(AddressB);
System.out.println(bfileContent);
String[] bStrings=kmp.ToArray(bfileContent);
for(int i=0;i<aStrings.length;i++){
System.out.println(aStrings[i]);
System.out.println(bStrings[i]);
int kmp1 = kmp.kmp(aStrings[i], bStrings[i]);
System.out.println(kmp1);
kmp.print();
kmp.fileWriter("D:\\DataStructer\\result.txt",kmp.writeContent(aStrings[i],bStrings[i]));
}
}
}
串的操作相关代码:
package String;
import java.util.Scanner;
/*串的操作
* */
public class StringDemo03 {
public char[] str; //使用字符数组存放串值
public static int curlen; //当前字符串的长度
//默认构造
public StringDemo03()
{
str = new char[0];
curlen = 0;
}
//以字符串常量构造串
public StringDemo03(String string)
{
char[] a = string.toCharArray();
str = a; //字符串可以直接赋值!
curlen = a.length;
}
//以字符数组构造串
public StringDemo03(char [] astr)
{
str = new char[astr.length]; //大小赋值
for(int i=0;i<astr.length;i++)
{
str[i] = astr[i]; //根据下标依次赋值
}
curlen = str.length; //更新串的长度!
}
//将串变为空串
public void clear()
{
curlen = 0;
}
//判断是否为空串
public boolean isEmpty()
{
return curlen==0;
}
//返回串的长度
public int length()
{
return curlen;
}
//返回位序号为i的字符
public char charAt(int i)
{
System.out.println(curlen);
if(i<0 || i>=curlen)
throw new StringIndexOutOfBoundsException(i); //如果不对则需要抛出异常!
return str[i];
}
//将串的长度扩充为newCapacity
public void allocate(int newCapacity) {
char [] tmp = str;//将旧的赋值
str = new char[newCapacity]; //将数组的大小扩充为新的参数值
for(int i=0;i<tmp.length;i++)
{
str[i] = tmp[i]; //再将旧的原来的元素复制进去
}
}
//返回位序号从begin到end-1的子串,注意,此处串的起始位置为0;
public String subString(int begin,int end)
{
if(begin<0||begin>=end||end>curlen)
throw new StringIndexOutOfBoundsException("the parameter is illegal!");
char []tmp = new char[end-begin];
for(int i=begin;i<end;i++)
{
tmp[i-begin] = str[i];
}
return String.valueOf(tmp);
}
//在第i个字符之前插入字串str
public void insert(int i,String aString)
{
if(i<0||i>curlen)
throw new StringIndexOutOfBoundsException("the inserted location is illegal");
int len = aString.length();//首先判断插入大小!
int newcapacity = len + curlen;//!!!对插入之后新形成的字符串的改变 重新分配存储空间
allocate(newcapacity); //重新分配存储空间
for(int j=curlen-1;j>=i;j--) //移动数据元素
{
str[j+len] = str[j];
}
for(int j=i;j<i+len;j++)
{
str[j] = aString.charAt(j-i);
}
}
//删除操作
public void delete(int begin,int end)
{
if(begin<0||end>curlen||begin>=end)
throw new StringIndexOutOfBoundsException("the parameter is illegal!");
for(int i=begin;i<end-1;i++)
{
str[i] = str[i+end-begin];
}
curlen = curlen-end+begin;
}
//打印字符串
public void print()
{
for(int i=0;i<str.length;i++)
{
System.out.print(str[i]);
}
System.out.println();
}
public static void main(String[] args) {
System.out.println("请输入你想要输入串中的数据!");
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
StringDemo03 aMain = new StringDemo03(s);
System.out.println("是否为空:"+aMain.isEmpty());
System.out.println("数组长度为:"+aMain.length());
System.out.print("特定位置的子串长度:");
System.out.println(aMain.subString(1, 4));
aMain.print();
System.out.println("请输入你想要插入的数据!");
String aString=scanner.nextLine();
System.out.println("请输入你想要插入的位置!");
int i=scanner.nextInt();
aMain.insert(i, aString);
aMain.print();
}
}