相似度匹配

数据结构综合实验报告 相似度匹配

一、需求分析

同学们的实验报告抄袭现象严重,现为了防止实验报告抄袭的恶习,让真正撰写实验报告的组能够获得公平的分数,需要设计一个系统能够查找两个实验报告中相同的文字内容,从而计算两个实验报告的相似度。

二、概要设计

给定2个字符序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。找到两个序列的最长公共子序列,其长度也就是两个序列中最长相同的文字模块数目
1、最长公共子序列
若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。
例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
例如:X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A}

2、问题:给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y
的最长公共子序列。
设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为
Z={z1,z2,…,zk} ,则
(1)若xm=yn,则zk=xm=yn,且zk-1是Xm-1和Yn-1的最长公共子序列。
(2)若xm≠yn且zk≠xm,则Z是Xm-1和Y的最长公共子序列。
(3)若xm≠yn且zk≠yn,则Z是X和Yn-1的最长公共子序列。

3、表达式
C[i][j]=0 i=0,j=0;
C[i][j]=c[i-1][j-1]+1 i,j>0;xi=yj;
C[i][j]=max{c[i-1][j],c[i][j-1]} i,j>0;xi!=yj;

三、详细设计

#include <iostream>
#include <stdlib.h>
#include<stdio.h>
#include<string.h>
#include"string"
#include<fstream>
#include <cassert>
//小学生英语作文房抄袭系统
using namespace std;

int IcsLength(string x,string y,int**& b){

    int m=x.length()-1;
    int n=y.length()-1;
    int c[m+1][n+1];
    //堆分配内存
    b=(int**)malloc((10000)*sizeof(int*));
    for (int i = 0; i < 10000; ++i){//为每列分配4个大小空间
        b[i] = (int*)malloc(sizeof(int)*10000);
    }
    int i,j;
    for(i=0;i<=m;i++)
        for(j=0;j<=n;j++)
            c[i][j]=0;
    for(i=1;i<=m;i++)
        for(j=1;j<=n;j++) {
            if (x[i] == y[j]) {
                c[i][j] = c[i - 1][j - 1] + 1;
                b[i][j] = 1;
            } else if (c[i - 1][j] >= c[i][j - 1]) {
                c[i][j] = c[i - 1][j];
                b[i][j] = 2;
            } else {
                c[i][j] = c[i][j - 1];
                b[i][j] = 3;
            }
        }
    return c[m][n];
}
//输出相似字数
void Ics(int i,int j,string x,int** b){
    if(i==0||j==0)
        return;
    if(b[i][j]==1){
        Ics(i-1,j-1,x,b);
        cout<<x[i];
    }else if(b[i][j]==2)
        Ics(i-1,j,x,b);
    else Ics(i,j-1,x,b);
}

int main(){
    string y;
    string x;
    char buf[1024];  /*缓冲区*/
    FILE *fp;            /*文件指针*/
    int len;             /*行字符个数*/
    if((fp = fopen("C://Users//Administrator//Desktop//xiangsidupipei//1.txt","r")) == NULL)
    {
        perror("fail to read");
        exit (1) ;
    }
    while(fgets(buf,1024,fp) != NULL)
    {
        len = strlen(buf);
        buf[len-1] = '\0';  /*去掉换行符*/
        //printf("%s %d \n",buf,len - 1);
    }
    x=buf;

    if((fp = fopen("C://Users//Administrator//Desktop//xiangsidupipei//2.txt","r")) == NULL)
    {
        perror("fail to read");
        exit (1) ;
    }
    while(fgets(buf,1024,fp) != NULL)
    {
        len = strlen(buf);
        buf[len-1] = '\0';  /*去掉换行符*/
        //printf("%s %d \n",buf,len - 1);
    }
    y=buf;

    int **b;
    int i=IcsLength(x,y,b);
    cout<<"相似字数:"<<endl;
    cout<<i<<endl;
    cout<<"相似段落:"<<endl;
    Ics(x.length()-1,y.length()-1,x,b);
    return 0;
}

四、测试结果

输入两篇文章:
在这里插入图片描述

五、问题分析

针对文字顺序变换这一抄袭现象,应该进行算法的改进。

发布了26 篇原创文章 · 获赞 39 · 访问量 1810

猜你喜欢

转载自blog.csdn.net/matafeiyanll/article/details/103401975