大家好:
我想做一个东西,功能方面不是太大,就是从数据库中依次读取文章,然后与用户输入的文章做比较。如果与一文章相似性超过某一设定的值,比如50%,就输出相似性较强的地方。
这个数据库等操作现在我可以实现,但没想好使用什么方法来进行相似性比较。我想过用栈实现,但想了半天又没法完全实现。大家帮我看看用什么方法实现比较合适。我总不能一个字一个字比较啊谢谢大家。

解决方案 »

  1.   

    《Faster Approximate String Matching》, Algorithmica (1999) 23: 127-158。
      

  2.   

    请问楼上的MARK是什么意思呢?谢谢。
      

  3.   

    package oa.file;
    import java.io.*;
    import java.util.*;
    import java.net.*;
    import java.sql.*;
    public class FileCompare2
    {
    private int[] iAdd=null,jAdd=null;
    private Vector vec=new Vector();//存放最大公共子串位置,形如:1,3|5,7表示s1的1-3与s2的5-7相匹配。

    private String s1,s2;
    private String info="",tmp="";

    public boolean getLargest(int s1_begin,int s1_end,int s2_begin,int s2_end)
    {
    try
    {
    int i=0,j=0,k=0;
    if(s1_end<=s1_begin||s2_end<=s2_begin)return false;
    //以s1为母串,s2为子串
    if(s1_end-s1_begin>=s2_end-s2_begin)
    {
    for(i=s2_end-s2_begin;i>=0;i--)
    {
    for(j=s2_begin;j+i<=s2_end;j++)
    {
    for(k=s1_begin;k+i<=s1_end;k++)
    {
    if(s1.substring(k,k+i+1).equals(s2.substring(j,j+i+1)))
    {
    //记录相同位置
    vec.add(k+","+(k+i)+","+j+","+(j+i));
    //递归查找
    getLargest(s1_begin,k-1,s2_begin,j-1);
    getLargest(k+i+1,s1_end,j+i+1,s2_end);
    return true;
    }
    }

    }
    }
    }
    //以s2为母串,s1为子串
    else
    {
    for(i=s1_end-s1_begin;i>0;i--)
    {
    for(j=s1_begin;j+i<=s1_end;j++)
    {
    for(k=s2_begin;k+i<=s2_end;k++)
    {
    if(s2.substring(k,k+i+1).equals(s1.substring(j,j+i+1)))
    {
    //记录相同位置
    vec.add(j+","+(j+i)+","+k+","+(k+i));
    //递归查找
    getLargest(s1_begin,j-1,s2_begin,k-1);
    getLargest(j+i+1,s1_end,k+i+1,s2_end);
    return true;
    }
    }

    }
    }


    }
    return false;
    }
    catch(Exception ex)
    {
    System.out.println(ex.toString());
    return false;
    }

    }
    //加入头尾标记
    public void insertComm(String head,String tail)
    {

    //取vec中的值,进行分解
    Enumeration en=vec.elements();
    String tmp="";
    //pos数组存放所有公共字串在两个串中的位置
    int pos1[][]=new int[vec.size()][2];
    int pos2[][]=new int[vec.size()][2];
    String []s=null;
    String str1="",str2="";
    //将字符串转换成数字
    int i=0,j=0;
    while(en.hasMoreElements())
    {
    tmp=(String)en.nextElement();
    s=tmp.split("[,]");
    pos1 [i][0]=Integer.parseInt(s[0]);
    pos1 [i][1]=Integer.parseInt(s[1]);
    pos2 [i][0]=Integer.parseInt(s[2]);
    pos2 [i][1]=Integer.parseInt(s[3]);
    i++;
    }
    /*
    //打印数组
    for(i=0;i<pos1.length;i++)
    {
    System.out.println("pos1:"+pos1[i][0]+","+pos1[i][1]);
    }
    for(i=0;i<pos2.length;i++)
    {
    System.out.println("pos2:"+pos2[i][0]+","+pos2[i][1]);
    }
    System.out.println("-----------------------"); */
    //对pos1和pos2根据起始位置进行排序
    int minPos=0,minValue=0;
    for(i=0;i<pos1.length;i++)
    {
    //选择排序
    minPos=i;
    for(j=i+1;j<pos1.length;j++)
    {
    if(pos1[j][0]<pos1[minPos][0])minPos=j;
    }
    if(minPos!=i)
    {
    //交换两数组的位置
    minValue=pos1[i][0];
    pos1[i][0]=pos1[minPos][0];
    pos1[minPos][0]=minValue;

    minValue=pos1[i][1];
    pos1[i][1]=pos1[minPos][1];
    pos1[minPos][1]=minValue;
    }

    }
    for(i=0;i<pos2.length;i++)
    {
    //选择排序
    minPos=i;
    for(j=i+1;j<pos2.length;j++)
    {
    if(pos2[j][0]<pos2[minPos][0])minPos=j;
    }
    if(minPos!=i)
    {
    //交换两数组的位置
    minValue=pos2[i][0];
    pos2[i][0]=pos2[minPos][0];
    pos2[minPos][0]=minValue;

    minValue=pos2[i][1];
    pos2[i][1]=pos2[minPos][1];
    pos2[minPos][1]=minValue;
    }

    }
    /*
    //打印数组
    for(i=0;i<pos1.length;i++)
    {
    System.out.println("pos1:"+pos1[i][0]+","+pos1[i][1]);
    }
    for(i=0;i<pos2.length;i++)
    {
    System.out.println("pos2:"+pos2[i][0]+","+pos2[i][1]);
    }
    */
    //对s1用pos1数组,插入头尾标记
    int sPos=0;
    for(i=0;pos1!=null&&i<pos1.length;i++)
    {
    str1=str1+s1.substring(sPos,pos1[i][0])+tail+s1.substring(pos1[i][0],pos1[i][1]+1)+head;
    sPos=pos1[i][1]+1;
    }
    if(sPos<s1.length())str1=str1+s1.substring(sPos);
    str1=head+str1+tail;

    //对s1用pos1数组,插入头尾标记

    sPos=0;
    for(i=0;pos2!=null&&i<pos2.length;i++)
    {
    //System.out.println(sPos+":"+pos2[i][0]+":"+pos2[i][1]);
    str2=str2+s2.substring(sPos,pos2[i][0])+tail+s2.substring(pos2[i][0],pos2[i][1]+1)+head;
    sPos=pos2[i][1]+1;
    }
    if(sPos<s2.length())str2=str2+s2.substring(sPos);
    str2=head+str2+tail;
    s1=str1;
    s2=str2;
    return ;

    }
    //找出所有公共子串
    public boolean compare(String m_s1,String m_s2)
    {
    if(m_s1==null||m_s2==null)return false;
    s1=m_s1;
    s2=m_s2;
    return getLargest(0,s1.length()-1,0,s2.length()-1);
    }
    public String getS1()
    {
    return s1;
    }
    public String getS2()
    {
    return s2;
    }
    public void pr()
    {
    System.out.println(s1);
    System.out.println(s2);
    //System.out.println(vec);

    }
    public static void main(String args[])
    {
    try
    {
    BufferedInputStream in=new BufferedInputStream(new FileInputStream("c:/1.txt"));
    byte []b=new byte[1024];
    int len=in.read(b);
    String s1="",s2="";
    while(len>0)
    {

    s1+=new String(b,0,len);
    len=in.read(b);
    }
    in.close();
    in=new BufferedInputStream(new FileInputStream("c:/2.txt"));
    len=in.read(b);
    while(len>0)
    {

    s2+=new String(b,0,len);
    len=in.read(b);
    }
    in.close();
    //System.out.println(s1);
    //System.out.println(s2);
    System.out.println(new java.util.Date().toLocaleString());
    FileCompare2 fc=new FileCompare2();
    fc.compare(s1,s2);
    System.out.println(new java.util.Date().toLocaleString());
    fc.insertComm("<a>","</a>");
    System.out.println(new java.util.Date().toLocaleString());
    //fc.pr();
    }
    catch(IOException iex)
    {
    System.out.println(iex.toString());
    }
    }
    }