使用c++从由字符串组成的文件中查找所有可能的公共子字符串

Finding all possible common substrings from a file consisting of strings using c++

本文关键字:字符串 查找 有可能 文件 c++ 使用      更新时间:2023-10-16

我正试图从一个由不同长度的字符串组成的文件中找到所有可能的公共字符串。有人能帮我吗?

E.g输入文件排序:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC    
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG
AAAAAAAATTAGGCTGGG
AAAAAAAATTGAAACATCTATAGGTC
AAAAAAACTCTACCTCTCT
AAAAAAACTCTACCTCTCTATACTAATCTCCCTACA

我想要的输出是:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC    
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG
AAAAAAAATTAGGCTGGG
AAAAAAAATTGAAACATCTATAGGTC
AAAAAAACTCTACCTCTCTATACTAATCTCCCTACA

[EDIT]作为任何其他行的子字符串的每一行都应删除。

基本上,对于每一行,将其与下一行进行比较,看看下一行是否更短,或者下一行的子字符串是否不等于当前行。如果这是真的,那么这条线是唯一的。这可以通过单个线性传递来完成,因为列表是排序的:任何包含条目子字符串的条目都将跟随在该条目后面。

非算法优化(微优化)是为了避免使用创建新字符串的子字符串。我们可以简单地比较另一个字符串,就好像它被截断了一样,而不需要实际创建截断的字符串。

vector<string> unique_lines;
for (unsigned int j=0; j < lines.size() - 2; ++j)
{
    const string& line = lines[j];
    const string& next_line = lines[j + 1];
    // If the line is not a substring of the next line,
    // add it to the list of unique lines.
    if (line.size() >= next_line.size() || 
        line != next_line.substr(0, line .size()))
        unique_lines.push_back(line);
}
// The last line is guaranteed to not be a substring of any
// previous line as the lines are sorted.
unique_lines.push_back(lines.back());
// The desired output will be contained in 'unique_lines'.

我所理解的是,你想找到子字符串,并想删除任何字符串的子字符串。为此,您可以使用strstr方法来查找一个字符串是否是另一个字符串的子字符串。希望这会有所帮助。。

好吧,这可能不是解决问题的最快解决方案,但似乎很容易实现。你只需要保留一个字符直方图,它将代表一个字符串的签名。对于你读取的每个字符串(用空格分隔),你计算每个字符的数量,如果没有其他字符串的每个字符的数字相同,就把它存储在你的答案中。让我举例说明:

aaa bbb aabb ab aaa

这里我们只有两个可能的输入字母,所以,我们只需要一个大小为2的直方图。

  • aaa-hist[0]=3,hist[1]=0:新的一个-添加到答案中
  • bbb-hist[0]=0,hist[1]=3:新的一个-添加到答案中
  • aabb-hist[0]=2,hist[1]=2:新的一个-添加到答案中
  • ab-hist[0]=1,hist[1]=1:新的-添加到答案中
  • aaa-hist[0]=3,hist[1]=0:已存在!不要增加答案

    实现的瓶颈将是直方图比较,并且有很多可能的实现。

    最简单的方法是简单的线性搜索,迭代所有以前的答案,并与当前直方图进行比较,其中O(1)用于存储,O(n)用于搜索。如果你有一个大文件,要花几个小时才能完成。

    一个更快但实现起来更麻烦的方法是使用哈希表来存储答案,并使用直方图签名来生成哈希代码。在这里解释这种方法会很麻烦。