同学们的实验报告抄袭现象严重,现为了防止实验报告抄袭的恶习,让真正撰写实验报告的组能够获得公平的分数,需要设计一个系统能够查找两个实验报告中相同的文字内容,从而计算两个实验报告的相似度。
给定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
#include
#include
#include
#include"string"
#include
#include
//小学生英语作文房抄袭系统
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;
}
针对文字顺序变换这一抄袭现象,应该进行算法的改进。