Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 两个文件上的Levenshtein距离占用太多时间_Python_C++_C_Optimization_Levenshtein Distance - Fatal编程技术网

Python 两个文件上的Levenshtein距离占用太多时间

Python 两个文件上的Levenshtein距离占用太多时间,python,c++,c,optimization,levenshtein-distance,Python,C++,C,Optimization,Levenshtein Distance,我是编程新手,我正在构建一个文件相似性查找器,它可以查找两个文件的相似性。 到目前为止,我将文件存储为两个字符串,然后使用levenshtein距离找出文件的相似性 问题是,没有levenshtein距离的执行时间是206ms,这是由于文件到字符串的转换。 当我使用levenshtein距离时,执行时间是惊人的19504毫秒 将文件转换为字符串所需时间的近95倍,这使得这成为我项目中的一个瓶颈 任何帮助都将不胜感激 我在C、C++和Python中很舒服。如果你能告诉我任何消息来源,我将不胜感激

我是编程新手,我正在构建一个文件相似性查找器,它可以查找两个文件的相似性。 到目前为止,我将文件存储为两个字符串,然后使用levenshtein距离找出文件的相似性

问题是,没有levenshtein距离的执行时间是206ms,这是由于文件到字符串的转换。 当我使用levenshtein距离时,执行时间是惊人的19504毫秒

将文件转换为字符串所需时间的近95倍,这使得这成为我项目中的一个瓶颈

任何帮助都将不胜感激 我在C、C++和Python中很舒服。如果你能告诉我任何消息来源,我将不胜感激

这里是用于计算LevsHeTin距离的函数的C++代码:< /P>

//LEVENSHTEIN
int levenshtein(std::string a, std::string b){
  int len_a = a.length();
  int len_b = b.length();
  int d[len_a + 1][len_b+1];

  for(int i = 0; i < len_a + 1; i++)
    d[i][0] = i;

  for(int j = 0; j < len_b + 1; j++)
    d[0][j] = j;

  for(int i = 1; i < len_a + 1; i++){
    for(int j = 1; j < len_b + 1; j++){
      if(a[i - 1] == b[j - 1]){
        d[i][j] = d[i - 1][j - 1];
      }
      else{
        d[i][j] = 1 + min(min(d[i][j-1],d[i-1][j]),d[i-1][j-1]);
      }
    }
  }

  int answer = d[len_a][len_b];

  return answer;
}
//LEVENSHTEIN
int levenshtein(标准::字符串a,标准::字符串b){
int len_a=a.length();
int len_b=b.长度();
INTD[len_a+1][len_b+1];
对于(int i=0;i
我只需要比较两个文件,而不是更多。我读过关于在levenshtein中使用trie的内容,但这对于将多个字符串与源代码进行比较非常有用。除此之外,我的运气不太好

有一个叫。看看吧

从nltk导入距离
打印(距离。编辑距离('aa','ab'))
输出:

1
有一个包裹叫。看看吧

从nltk导入距离
打印(距离。编辑距离('aa','ab'))
输出:

1

我将给你看一个C++解决方案。使用的语言是C++17。编译器是MS Visual Studio Community 2019。在发布模式下编译,并启用所有优化

我用“Lorem ipsum sum”生成器创建了两个1000字的文件。每个文件的文件大小约为6kB

结果一眨眼就可以得到

我使用了一个稍微修改过的levenstein函数,并且使用了更可读的变量名。我不使用VLA(可变长度数组),因为这在C++中是无效的。我使用了一个std::vector,它甚至具有更好的功能

大体上,我们可以看到驱动程序代码。首先,我们打开2个输入文件,检查它们是否可以打开。如果没有,我们将显示一条错误消息并退出程序

然后,我们使用
std::string
范围构造函数和
std::istreambuf\u迭代器将2个文本文件读入2个字符串。我不知道有什么更简单的方法可以将完整的文本文件读入
std::string

然后我们打印距离内的levenstein结果

请参阅下面的代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iterator>

// Distance between 2 strings
size_t levensthein(const std::string& string1, const std::string& string2)
{
    // First get the string lengths
    const size_t lengthString1{ string1.size() };
    const size_t lengthString2{ string2.size() };

    // If one of the string length is 0, then return the length of the other
    // This results in 0, if both lengths are 0
    if (lengthString1 == 0) return lengthString2;
    if (lengthString2 == 0) return lengthString1;

    // Initialize substitition cost vector
    std::vector<size_t> substitutionCost(lengthString2 + 1);
    std::iota(substitutionCost.begin(), substitutionCost.end(), 0);

    // Calculate substitution cost
    for (size_t indexString1{}; indexString1 < lengthString1; ++indexString1) {
        substitutionCost[0] = indexString1 + 1;
        size_t corner{ indexString1 };

        for (size_t indexString2{}; indexString2 < lengthString2; ++indexString2) {
            size_t upper{ substitutionCost[indexString2 + 1] };
            if (string1[indexString1] == string2[indexString2]) {
                substitutionCost[indexString2 + 1] = corner;
            }
            else {
                const size_t temp = std::min(upper, corner);
                substitutionCost[indexString2 + 1] = std::min(substitutionCost[indexString2], temp) + 1;
            }
            corner = upper;
        }
    }
    return substitutionCost[lengthString2];
}

// Put in your filenames here
const std::string fileName1{ "text1.txt" };
const std::string fileName2{ "text2.txt" };

int main() {

    // Open first file and check, if it could be opened
    if (std::ifstream file1Stream{ fileName1 }; file1Stream) {

        // Open second file and check, if it could be opened
        if (std::ifstream file2Stream{ fileName2 }; file2Stream) {

            // Both files are open now, read them into strings
            std::string stringFile1(std::istreambuf_iterator<char>(file1Stream), {});
            std::string stringFile2(std::istreambuf_iterator<char>(file2Stream), {});

            // Show Levenstehin distance on screen
            std::cout << "Levensthein distance is: " << levensthein(stringFile1, stringFile2) << '\n';
        }
        else {
            std::cerr << "\n*** Error. Could not open input file '" << fileName2 << "'\n";
        }
    }
    else {
        std::cerr << "\n*** Error. Could not open input file '" << fileName1 << "'\n";
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//两个字符串之间的距离
大小(常量标准::字符串和字符串1,常量标准::字符串和字符串2)
{
//首先得到字符串的长度
const size_t lengthString1{string1.size()};
const size_t lengthString2{string2.size()};
//如果其中一个字符串长度为0,则返回另一个字符串的长度
//如果两个长度均为0,则结果为0
如果(lengthString1==0)返回lengthString2;
如果(lengthString2==0)返回lengthString1;
//初始化替代成本向量
std::载体替代成本(长度2+1);
std::iota(substitutionCost.begin(),substitutionCost.end(),0);
//计算替代成本
对于(size_t indexString1{};indexString1STD::CUT< P>我将给你展示一个C++解决方案。使用的语言是C++ 17。编译器是MS VisualStudio社区2019。
我用“Lorem ipsum sum”生成器创建了两个1000字的文件。每个文件的大小约为6kB

结果一眨眼就可以得到

我使用了一个简单的修改的LeaveSein函数,也使用了更多的可读变量名。我不使用VLA(可变长度数组),因为这在C++中是无效的。我使用了<代码> STD::vector < /C> >,它具有更优越的功能。

大体上,我们可以看到驱动程序代码。首先,我们打开两个输入文件,检查它们是否可以打开。如果不能打开,我们会显示一条错误消息并退出程序

然后我们通过u将2个文本文件读入2个字符串