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

时间:2012-02-03 11:35:56

标签: c++ string file

我试图从包含各种长度的字符串的文件中找到所有可能的公共字符串。有人可以帮帮我吗?

E.g输入文件已排序:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC    
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG
AAAAAAAATTAGGCTGGG
AAAAAAAATTGAAACATCTATAGGTC
AAAAAAACTCTACCTCTCT
AAAAAAACTCTACCTCTCTATACTAATCTCCCTACA

我想要的输出是:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC    
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG
AAAAAAAATTAGGCTGGG
AAAAAAAATTGAAACATCTATAGGTC
AAAAAAACTCTACCTCTCTATACTAATCTCCCTACA

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

  

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)。如果您有一个大文件,则需要数小时才能完成。

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

答案 2 :(得分:0)

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

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

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'.