C++/JAVA 计算两篇文章的相似度

这位少侠,要不要进店瞧瞧?

实验介绍及思路

问题描述:

编写程序,计算任意两篇文章的相似度。

基本思路:

利用余弦相似度来计算其相似度。

完整代码

C++ 代码来啰

/*
*
* Author    :       YU.J.P
* Time      ;       2022/04/03
* Project   :       Experment One -- calculate article similarity.
*
*///计算两篇文章的相似度#include "bits/stdc++.h"
//#include <iostream>
//#include <cstring>#define MAXSIZE 1024  //预设最大容量
using namespace std;/* 单词顺序表 */
typedef struct word
{char str[32];      //单词最大长度设为32int cnt = -1;      //单词出现次数,-1表示没有元素
}wordList;/* 读取文件中的单词 */
void readFile(string fileName, wordList* words)
{char temp[32];                     //读取单词变量int netWords = 0, total = 0;      //去重单词个数,单词出现次数int newWordflag = 1;             //newWord标志位,判断是否为新单词(查重) ifstream ifs;                      //1.创建流对象;ifs.open(fileName , ios::in);     if (!ifs.is_open())                 //2.打开文件 ifs.open("文件路径",打开方式);{cout << "\n文件打开失败!" << endl;}cout << "\n文件打开成功!" << endl;char character[] = ",.:\"!";     //英文标点符号while (ifs >> temp)                   //3.读数据 4种读取方式{for (int j = 0; temp[j] != '\0'; j++)  //清除符号{                                     //判断是否有符号if (strchr(character, temp[j]) != NULL)temp[j] = '\0';                 // 如果文本符号没有分隔开,会出错}newWordflag = 1;for (int i = 0; i < netWords; i++){if (strcmp(temp, words[i].str) == 0)//重复的单词{newWordflag = 0;words[i].cnt++;}}if (newWordflag){strcpy_s(words[netWords].str, temp);words[netWords++].cnt = 1;            //新单词数量+1 }}for (int i = netWords - 1; i >= 0; i--)       //单词出现次数{total += words[i].cnt;}ifs.close();                      //4.关闭文件 ifs.close();//打印n和scout << "netWords = " << netWords << "\ttotal = " << total << endl;}/* 获得合并keyWord数组target */
void getKeyWord(wordList* target,wordList* article1, wordList* article2)
{//复制一个数组int i;//新单词递增位for (i = 0; article1[i].cnt != -1 && i < MAXSIZE; i++){strcpy_s(target[i].str,article1[i].str);   //复制单词target[i].cnt = 0;                           //清零}//添加另一个数组不同的单词for (int j = 0; article2[j].cnt != -1 && j < MAXSIZE; j++){int newWordFlag = 1;                      //新单词标志位for (int v = 0; article2[v].cnt != -1 && v < MAXSIZE; v++){if (strcmp(article2[j].str, target[v].str) == 0){                                       //重复的单词newWordFlag = 0;}}if (newWordFlag == 1){strcpy_s(target[i].str, article2[j].str); //复制单词target[i++].cnt = 0;                       //清零 i++递增}}
}/* 统计词频 */
void statistics(wordList* target, wordList* article, int* wordsNum)
{for (int i = 0; target[i].cnt != -1 && i < MAXSIZE; i++){                               //外循环遍历targetfor (int j = 0; article[j].cnt != -1 && j < MAXSIZE; j++){                          //内循环遍历articleif (strcmp(target[i].str,article[j].str) == 0)//相同{                     //包含此单词,复制频数wordsNum[i] = article[j].cnt;break;}}if(wordsNum[i] == -1)       //没有此单词标记为0wordsNum[i] = 0;}
}/* 计算相似度 */
double calSimilarity(int* a, int* b)
{double squareSum = 0;             //平方和       分子double sqrtSumA = 0, sqrtSumB = 0;  //平方和开方 分母for (int i = 0; a[i] != -1; i++){squareSum += (double)a[i] * (double)b[i];sqrtSumA += pow(a[i],2);sqrtSumB += pow(b[i], 2);}sqrtSumA = sqrt(sqrtSumA);sqrtSumB = sqrt(sqrtSumB);double Cos = squareSum / (sqrtSumA * sqrtSumB);return Cos;
}/* 打印单词结构体中的单词 */
void printWordList(wordList* articleWords)
{for (int i = 0; articleWords[i].cnt != -1 && i < MAXSIZE; i++){//预设打印宽度20,左对齐cout << articleWords[i].str << setw(20) << setiosflags(ios::left);if ((i + 1) % 5 == 0)        //打印换行cout << endl;}cout << endl;
}/* 打印统计单词频数 */
void printWordsNum(int* WordsNum)
{for (int i = 0; WordsNum[i] != -1 && i < MAXSIZE; i++){cout << WordsNum[i] << "\t";if ((i + 1) % 10 == 0)      //打印换行cout << endl;}cout << endl;
}/* MAIN */
int main()
{cout << "\t计算文章相似度\n" << endl;wordList articleWords1[MAXSIZE];               //单词数量上限1024wordList articleWords2[MAXSIZE];                //单词数量上限1024wordList target[MAXSIZE];                       //keyWordint wordsNum1[MAXSIZE];                            //article 1 statisticsint wordsNum2[MAXSIZE];                           //article 2 statisticsreadFile("article1.txt", articleWords1);  //查找单词写入结构体cout << "\n**************** article1 words ***************" << endl;printWordList(articleWords1);                    //打印单词cout << "\n***********************************************" << endl;readFile("article2.txt", articleWords2);  //查找单词写入结构体cout << "\n**************** article2 words ***************" << endl;printWordList(articleWords2);                  //打印单词cout << "\n***********************************************" << endl;getKeyWord(target,articleWords1, articleWords2);cout << "\n**************** target   words ***************" << endl;printWordList(target);                            //打印单词cout << "\n***********************************************" << endl;memset(wordsNum1, -1, MAXSIZE * sizeof(int));                   //初始化元素为-1statistics(target, articleWords1, wordsNum1); //统计wordsNum1cout << "\n**************** wordsNum1 ***************" << endl;printWordsNum(wordsNum1);                     //打印wordsNum1cout << "\n******************************************" << endl;memset(wordsNum2, -1, MAXSIZE * sizeof(int));                 //初始化元素为-1statistics(target, articleWords2, wordsNum2); //统计wordsNum2cout << "\n**************** wordsNum2 ***************" << endl;printWordsNum(wordsNum2);                     //打印wordsNum2cout << "\n******************************************" << endl;cout << "两文章的相似度为: " << setw(5) << setprecision(2) << setiosflags(ios::fixed) << setiosflags(ios::right) << calSimilarity(wordsNum1, wordsNum2) * 100 << "%" << endl;//小数2位cout << "\nOver..." << endl;return 0;
}

JAVA 代码来啰

/*
*
* Time      :   2022/04/02
* Author    :   YU.J.P
* Project   :   Duplicate checking by using cosine formula.
* version   :   V1.0.0
*
*//* Import... */
import java.io.File;            //File类
import java.util.ArrayList;     //ArrayList类
import java.util.List;          //List类
import java.util.Scanner;       //Scanner类public class Experment_0402 {/** MAIN */public static void main(String[] args) {judgeArticle();}/*** discription: 判断两篇文章的相似度。采用余弦相似度来计算两文章的相似度。* */public static void judgeArticle(){String str1 = readFile("txtData/article1.txt");//读入文章1String str2 = readFile("txtData/article2.txt");//读入文章2System.out.println("article 1 为:" + str1);System.out.println();System.out.println("article 2 为:" + str2);System.out.println();//获得str的字符数组List<String> list1 = changeToList(str1);List<String> list2 = changeToList(str2);//获得去重listList<String> strSpilt = fixTwoStringArr(list1, list2);System.out.println("去重字符数组为:");for (int i = 0; i < strSpilt.size(); i++) {System.out.print(strSpilt.get(i) + " ");}//获得词频int[] wordNum1 = getWordFrequency(strSpilt, list1);int[] wordNum2 = getWordFrequency(strSpilt, list2);System.out.println("\nstr1文本词频为:");for (int i = 0; i < wordNum1.length; i++) {System.out.print(wordNum1[i] + " ");}System.out.println("\nstr2文本词频为:");for (int i = 0; i < wordNum2.length; i++) {System.out.print(wordNum2[i] + " ");}//获得相似度System.out.printf("\n\narticle1与article2的相似度为:%.2f%%\n" , calSimilarity(wordNum1, wordNum2)*100);}/*** discription: 读取文件中的文章到字符串* @param   fileName  A pathname string* @throws* */public static String readFile(String fileName) {//给地址 如"txtData/article1.txt"String str = "", temp = "";//字符串str 临时单词变量temptry {File file = new File(fileName);//文件对象Scanner in = new Scanner(file);//文件输入流while (in.hasNext()) {temp = in.next();
//                System.out.print(temp + " ");
//                char a = temp.charAt(temp.length() - 1);
//                if (a == '.' || a == '?' || a == '!')//去符号
//                    System.out.println();str += temp + " ";//将每次的单词加入str,末尾加空格}in.close();//关闭输入流} catch (Exception e) {//抛出错误System.out.println(e.getMessage());}return str;}/*** discription: 将字符串转化成list* @param   str  需要转化为list的字符串* @throws* */public static List<String> changeToList(String str) {String[] string = str.split(" ");//分词List<String> list = new ArrayList<>();for (int i = 0; i < string.length; i++) {list.add(string[i]);}return list;}/*** discription: 合并两个字符串list,去掉重复单词* @param   list1  字符串List<String> list1* @param   list2  字符串List<String> list2* @throws* */public static List<String> fixTwoStringArr(List<String> list1, List<String> list2) {List<String> list = new ArrayList<>();//处理list1for (int i = 0; i < list1.size(); i++) {if (!list.contains(list1.get(i))) {list.add(list1.get(i));}}//处理list2for (int i = 0; i < list2.size(); i++) {if (!list.contains(list2.get(i))) {list.add(list2.get(i));}}return list;}/*** description: 获得文本词频* @param   target  去重后的对比字符串List<String> target* @param   list  传入比较字符串List<String> list* @throws* */public static int[] getWordFrequency (List<String> target, List<String> list) {int[] wordFrequency = new int[target.size()];//创建数组for (int i = 0; i < list.size(); i++) {//外循环遍历listfor (int j = 0; j < target.size(); j++) {//内循环遍历target,如果对应位置单词出现则+1if (target.get(j).equals(list.get(i))) {wordFrequency[j]++;break;}}}return wordFrequency;}/*** discription: 根据n维向量余弦公式得到相似度* @param   x  第一个文章的文本词频* @param   y  第二个文章的文本词频* @throws* */public static double calSimilarity(int[] x, int[] y) {double squareSum = 0;                 //平方和     分子double sqrtSumA = 0, sqrtSumB = 0;    //平方和开方   分母for (int i = 0; i < x.length; i++) {squareSum += x[i] * y[i];sqrtSumA += Math.pow(x[i], 2);sqrtSumB += Math.pow(y[i], 2);}return squareSum / (Math.sqrt(sqrtSumA) * Math.sqrt(sqrtSumB));}}

少侠慢走…不妨先点一个赞鼓励一下作者。。。

C++/JAVA 计算两篇文章的相似度相关推荐

  1. python余弦定理_使用余弦定理计算两篇文章的相似性

    使用余弦定理计算两篇文章的相似性:(方法论,细致易懂版) http://blog.csdn.net/dearwind153/article/details/52316151 python 实现(代码) ...

  2. 【python 走进NLP】simhash 算法计算两篇文章相似度

    互联网网页存在大量的重复内容网页,无论对于搜索引擎的网页去重和过滤.新闻小说等内容网站的内容反盗版和追踪,还是社交媒体等文本去重和聚类,都需要对网页或者文本进行去重和过滤.最简单的文本相似性计算方法可 ...

  3. [将小白进行到底] 如何比较两篇文章的相似度

    其实这个题目已经有很多人写过了,数学之美里就有,最近阮一峰的博客里也写了,本文基本上遵循的就是他的思路,只是让其看起来再小白一点点.其实说白了就是用自己的话,再把同样一件事描述一下,顺便扩扩句,把其中 ...

  4. php类似if,php 比较两篇文章的相似度的方法

    昨天说了一下php中的 similar_text() 函数,此函数可以比较两个字符串之间的相似度(以百分比计),但此函数在比较中文字符串时感觉不是那么的准确. 在网上搜索了一些php用户比较两个中文字 ...

  5. 比较两篇文章的相似性方法

       对于这个题目,开始毫无头绪,后来经过查阅资料现在讲方法总结如下:   1.利用余弦定理    我们知道向量a,b之间的夹角可用余弦定理求得:              如果夹角的余弦值越小,那么 ...

  6. 计算两组标签/关键词 相似度算法

    原文连接 http://www.zhaochao.net/index.php/2016/02/05/14/ 写作背景 标签在互联网行业有大量的应用,给博客打标签,给商品打标签,给新闻打标签.通常每篇文 ...

  7. 【NLP学习笔记】文本相似度计算——判断两篇文章是否相似

    一.算法流程 (1)使用TF-IDF算法,提取出两篇文章的关键词: (2)每篇文章各取出若干个关键词(比如20个),合并成一个集合,计算每篇文章对于这个集合中的词的词频(为了避免文章长度的差异,可以使 ...

  8. 【读书笔记】NeurIPS2018的两篇文章:The Tradeoffs of Large Scale Learning和Neural Ordinary Differential Equations

    今天看了 NeurIPS 2018 上的两篇文章,一篇是获得 best paper 的 Neural Ordinary Differential Equations (陈天奇的文章),一篇是获经典论文 ...

  9. 目前需要开发出一个功能,对比查找并标注出两篇文章中类似的段落或者词句,有什么开源项目有这个功能吗? 其实有点像论文查重的功能,有论文查重的比较通用的开源项目推荐吗?...

    是的,你可以使用论文查重的工具来对比查找并标注两篇文章之间的相似段落或词句. 你可以尝试使用这些开源项目: MOSS (Measure Of Software Similarity):这是一个用于检测 ...

最新文章

  1. OpenStack Rally 质量评估与自动化测试利器
  2. jboss 配置上下文路径_JBoss Portal上的“ Hello World” portlet
  3. java swing 如何设置按钮大小_Java Swing - Button不改变宽度的大小
  4. System Center Configuration Manager 2016 域准备篇(Part2)
  5. 剑指_5替换空格(Python)
  6. 【Android】【移动应用开发】基础知识
  7. 机器学习笔记:训练集、验证集与测试集
  8. word怎么竖向选中,word怎么文字竖排的两种方法
  9. 变电站无线测温系统的特点与应用
  10. 【基础知识①】计算机网络知识
  11. 喝酒骑行电瓶车属于违法或者犯罪吗?
  12. 1Password 7.3.2 强大的密码管理器
  13. python社区微信群_Python 打造微信群聊天机器人(带操作界面)-Go语言中文社区...
  14. 名帖51 王羲之 小楷《佛遗教经》
  15. 解决谷歌浏览器提示Google账号无法登录提示浏览器或应用不安全问题
  16. 三 创建纵断面图和纵断面
  17. 算法基础课【合集2】
  18. 关于知网学位论文检测系统的说明及修改指导意见
  19. 2600路由密码恢复
  20. 边坡安全监测系统的主要内容

热门文章

  1. windows10应用程序需要设置管理员权限自启动
  2. Win7系统服务优化攻略
  3. MySQL RR隔离级别解决幻读问题?
  4. 【吾日三省吾身】2015.5.19-慎独、慎言、慎行、戒骄、戒躁、戒怒
  5. Android和风天气sdk
  6. [从头读历史] 第309节 星球战争 BC2499 至 BC2400(公元前25世纪)
  7. L2-039 清点代码库
  8. circular 字体_Circular Regular
  9. 【APICloud系列|15】上架ios应用到苹果应用市场总结
  10. 4. struct 结构体