【问题标题】:Finding percentage of similarity among some text files查找某些文本文件之间的相似度百分比
【发布时间】:2016-11-08 05:25:01
【问题描述】:

我用 C++ 编写了一个程序,它根据整数变量 v 在 1 到 100 之间变化的值序列生成一个文本文件。文本文件格式如下:

file1.txt
1 2 3 4 5

file2.txt
4 5 6 7 8

file3.txt
8 4 5 7 1

.......

比如说,我已经生成了 100 个文本文件(file1.txtfile100.txt)。我想一一检查文本文件并找出它们之间的相似度百分比。 我不想检查所有 100 个文本文件,而是想在某些连续文件获得或多或少相似的结果时停止检查。

如何执行相似性检查?比如说,我计算了 file1 和 file2 之间的相似度百分比。现在我将计算 file2 和 file3 或 file1 和 file3 等的相似度吗? 更准确地说,执行此检查的逻辑是什么?

【问题讨论】:

  • 你如何看待相似度?是分享一些信件吗?分享一些话?还是订单也相关?例如。 12345 更类似于 54321 还是 12457 ?
  • 12345 与 54321 更相似。通过相似性,我的意思是说两个文件将包含最多相同的数字@Christophe
  • 为什么会有standard-deviation这个标签?您打算对标准差进行统计计算吗?
  • 您必须更准确地定义“相似”,并且您还需要定义您希望输出的内容。您是否想知道哪个文件与 file1 最相似,哪个文件与 file2 最相似等等,以便您有一个显示每个文件以及哪个文件最相似的列表?如果文件 1、17 和 26 相同,你会怎么做?如果文件 1 包含 12345,而其他文件都不包含这些数字怎么办?如果没有明确说明您的输出,我们给您的任何建议都可能是错误的。

标签: c++ algorithm file logic standard-deviation


【解决方案1】:

根据你们的cmets,相似度是根据共同的位数来计算的,不管它们的顺序。

两个文件之间的相似性

最简单的方法是将load 两个连续的文件(比如两个打开的ifstream sfs1sts2)分成两个向量:

std::vector<int> v1{1,2,3,4,5,6,7,8};

    copy(istream_iterator<int>(sfs1), istream_iterator<int>(), back_inserter(v1));
    copy(istream_iterator<int>(sfs2), istream_iterator<int>(), back_inserter(v2));

Sort 向量:

    sort(v1.begin(), v1.end()); 
    sort(v2.begin(), v2.end()); 

然后使用标准算法取两个排序向量的intersection

    set_intersection(v1.cbegin(), v1.cend(), v2.cbegin(), v2.cend(), back_inserter(sim));

然后你只需要寻找尺寸:

    cout << "Similar elements: " << sim.size()<<endl; 
    cout << "Similarity coefficient: "<< (double)sim.size()/max(v1.size(), v2.size())*100 <<"%"<<endl;  

现在您必须添加一些错误处理,以防两个向量都为空(这将导致此处除以 0)。

这里是 online demo 使用字符串流而不是文件流:

如何处理多个文件

根据您的问题,您不需要在每对可能的文件中寻找相似之处,而只需要在后续文件之间寻找相似之处。

所以在你比较了前两个文件后,你只需将v2复制到v1,将下一个文件读入v2并排序。并计算新的相似度。

您还需要有一个计数器来计算连续的近似匹配。每次相似度超过某个阈值(例如 90%)时增加它。每次相似度低于时将其重置为 0。一旦您的计数器达到您期望的连续接近匹配的数量,就停止:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多