#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <string>
#include <string.h>
#include <sstream>
#include <cstdlib>
#include <fstream>
#include <cassert>
#include <algorithm>
#include <math.h>
#include <iterator>
#include <cctype>

using namespace std;

typedef struct Sentence {
	string sentence;	//记录句子
	int num;			//记录句子单词个数
}Sentence;

typedef struct sameSentence {
	string libsent;     //记录对到最长公共子序列的lib的句子
	string textsent;    //记录test中对比的句子
	int textnum;		//记录test中对比的句子的单词的个数
	int samenum;	    //最长公共子序列的单词个数
}sameSentence;

sameSentence saveall[1000];   //存储所有对比好的信息

Sentence libSentence[1000];     //按句存储lib文件的内容
int wordSimilarity[1000][1000];
float Score[1000][1000];      //记录最长公共子序列的得分
string str1[1000], str2[1000];   //存储每个句子分割出来的单词

int libline = 0;     //lib文件的句子的个数
int testline = 0;    //test文件的句子的个数

void libtxtToSentence(string file);  // 把lib里的内容按句子存储
void textToSentence(string file);   // 读取text文本的内容并使用动态规划进行查重
float max(float a, float b);
float maxthree(float a, float b, float c);


int main()
{
	int j;
	string libfile = "D://lib.txt";
	string textfile = "D://text.txt";

	libtxtToSentence(libfile);

	textToSentence(textfile);

	for (j = 0; j < testline; j++)
	{
		cout << "第" << j + 1 << "句对比" << endl;
		cout << saveall[j].textsent << endl;
		cout << saveall[j].libsent << endl;
		cout << saveall[j].samenum << "\t" << saveall[j].textnum << endl;
		cout << "\n" << endl;
	}

	return 0;
}


void libtxtToSentence(string file)   // 把lib里的内容按句子存储
{
	ifstream infile;
	infile.open(file.data());   //将文件流对象与文件连接起来 
	assert(infile.is_open());   //若失败,则输出错误消息,并终止程序运行 

	char currentChar;
	string tempSentence = "";
	Sentence temp;
	int num1 = 0;

	infile >> noskipws;

	while (!infile.eof())
	{
		infile >> currentChar;

		if (((currentChar >= 'a') && (currentChar <= 'z')) || ((currentChar >= 'A') && (currentChar <= 'Z')))
		{
			tempSentence += currentChar;

		}
		else if ((currentChar == '.') || (currentChar == '?') || (currentChar == '!'))
		{
			transform(tempSentence.begin(), tempSentence.end(), tempSentence.begin(), ::tolower);
			temp.num = num1 + 1;
			temp.sentence = tempSentence;
			libSentence[libline] = temp;     //按每句子存储lib的内容到libSentence[]中
			num1 = 0;
			tempSentence = "";
			libline++;      //lib文件的句子的个数
		}
		else    //匹配到空格
		{
			if (tempSentence == "")
			{
				continue;
			}
			else if (tempSentence[tempSentence.size() == 1 ? 1 : tempSentence.size() - 1] != ' ')  //匹配到空格,当前句末不为空格,添加空格
			{
				tempSentence += " ";
				num1 += 1;    //单词个数加1
			}
		}
	}
	infile.close();             //关闭文件输入流 
}


void textToSentence(string file)    // 读取text文本的内容并使用动态规划进行查重
{
	ifstream infile;
	infile.open(file.data());   //将文件流对象与文件连接起来 
	assert(infile.is_open());   //若失败,则输出错误消息,并终止程序运行 

	char currentChar;
	string tempSentence = "";
	Sentence temp;
	int num1 = 0;

	infile >> noskipws;

	while (!infile.eof())
	{
		infile >> currentChar;

		if (((currentChar >= 'a') && (currentChar <= 'z')) || ((currentChar >= 'A') && (currentChar <= 'Z')))
		{
			tempSentence += currentChar;

		}
		else if ((currentChar == '.') || (currentChar == '?') || (currentChar == '!'))   //完成一个句子的读取,进行动态规划匹配查重
		{
			transform(tempSentence.begin(), tempSentence.end(), tempSentence.begin(), ::tolower);
			temp.num = num1 + 1;            // 把当前读取到的test句子的单词个数存下
			temp.sentence = tempSentence;  // 把当前读取到的test句子存下 
			num1 = 0;
			tempSentence = "";

			for (int i = 0; i < libline - 1; i++)   //分别与lib中的每一句进行对比
			{
				string t;
				int n = 0;
				int k, j;

				for (istringstream is(temp.sentence); is >> t;) {   //存储把test的句子分割出来的单词
					str1[n++] = t;
				}

				n = 0;
				for (istringstream is1(libSentence[i].sentence); is1 >> t;) {   //存储把lib的句子分割出来的单词
					str2[n++] = t;
				}

				for (k = 0; k < temp.num; k++)   //test当前句子的个数
				{
					for (j = 0; j < libSentence[i].num; j++)  //与lib文件的句子的单词分别进行对比
					{
						if (str1[k] == str2[j])
							wordSimilarity[k][j] = 1;
						else
							wordSimilarity[k][j] = 0;
					}
				}

				for (k = 0; k < temp.num; k++)
				{
					Score[k][0] = max(Score[k - 1][0] - 0.5, wordSimilarity[k][0] - 0.5 * (k - 1));
				}
				for (k = 0; k < libSentence[i].num; k++)
				{
					Score[0][k] = max(Score[0][k - 1] - 0.5, wordSimilarity[0][k] - 0.5 * (k - 1));
				}
				for (k = 1; k < temp.num; k++)
				{
					for (j = 1; j < libSentence[i].num; j++)
					{
						Score[k][j] = maxthree(Score[k - 1][j] - 0.5, Score[k][j - 1] - 0.5, Score[k - 1][j - 1] + wordSimilarity[k][j]);
					}
				}

				int sum = Score[temp.num - 1][libSentence[i].num - 1];

				if (saveall[testline].samenum < sum)
				{
					saveall[testline].libsent = libSentence[i].sentence;
					saveall[testline].samenum = sum;
					saveall[testline].textnum = temp.num;
					saveall[testline].textsent = temp.sentence;
				}
			}
			testline++;   //test文件的句子的个数

		}
		else  //匹配到空格
		{
			if (tempSentence == "")
			{
				continue;
			}
			else if (tempSentence[tempSentence.size() == 1 ? 1 : tempSentence.size() - 1] != ' ') //匹配到空格,当前句末不为空格,添加空格
			{
				tempSentence += " ";
				num1 += 1;
			}
		}
	}
	infile.close();             //关闭文件输入流 
}


float max(float a, float b)
{
	if (a > b)
		return a;
	else
		return b;
}


float maxthree(float a, float b, float c)
{
	float temp = a;

	if (temp < b)
		temp = b;
	if (temp < c)
		temp = c;

	return temp;
}

解释以上程序内容:这段程序是一个文本查重的程序,主要实现了以下功能:

  1. 程序包含的头文件有stdio.h、stdlib.h、iostream、iomanip、string、string.h、sstream、cstdlib、fstream、cassert、algorithm、math.h、iterator、cctype。这些头文件提供了各种输入输出、字符串处理、文件操作、算法等功能的函数和类。

  2. 程序定义了两个结构体Sentence和sameSentence,分别用于存储句子和对比结果的信息。

  3. 程序定义了全局变量libSentence、wordSimilarity、Score、str1、str2、saveall、libline和testline,用于存储lib文件的句子、单词相似度矩阵、最长公共子序列得分矩阵、分割出来的test句子单词、对比结果的数组、lib文件的句子个数和test文件的句子个数。

  4. 程序实现了libtxtToSentence函数,用于将lib文件的内容按句子存储到libSentence数组中。

  5. 程序实现了textToSentence函数,用于读取text文件的内容并使用动态规划进行查重。该函数先将读取到的句子存储到temp结构体中,然后与libSentence数组中的每一句进行对比,计算最长公共子序列得分,并将对比结果存储到saveall数组中。

  6. 程序实现了max和maxthree函数,用于比较两个或三个数的大小,返回较大的数。

  7. 主函数main中,先调用libtxtToSentence函数将lib文件的内容按句子存储。然后调用textToSentence函数读取text文件的内容并进行查重。最后输出对比结果。

总的来说,这段程序通过动态规划算法实现了文本查重的功能,可以对比两个文件中的句子并计算它们之间的相似度。

C++ 文本查重程序:使用动态规划算法计算句子相似度

原文地址: http://www.cveoy.top/t/topic/blX9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录