计算子串的出现次数

时间:2013-10-15 19:30:55

标签: c++ c

是否有一种有效的算法来计算较长字符串X中子字符串Y的出现总次数?

更具体地说,我想要的是从B中选择A.size()元素的总方式,以便存在与B匹配的所选元素的排列。

示例如下:搜索字符串X=ABY=ABCDBFGHIJ的总出现次数?

答案是2:第一个A和第二个B,第一个A和第5个B.

我知道我们可以生成长字符串的所有排列(将N!长度N字符串Y)并使用KMP算法来搜索/计算{{1}的出现次数在X中。

我们能做得更好吗?

我试图解决的原始问题如下:假设我们有一个大的矩阵M,大小为r乘以c(r和c在10000的范围内)。给定尺寸a乘b的小矩阵P(a和b在10的范围内)。找到M的行和b列的不同选择的总数(这将给出a a b“子矩阵”H),以便存在H的行和列的排列,它给出了一个匹配P的矩阵

我认为一旦我能解决1-D案例,2-D可能会遵循解决方案。

经过研究,我发现这是一个子图同构问题,它是NP难的。有一些算法有效地解决了这个问题。人们可以谷歌并看到很多论文。

2 个答案:

答案 0 :(得分:1)

阅读之后,重新阅读问题(在@Charlie的建议下),我得出结论,这些答案并没有解决真正的问题。我还得出结论,我仍然不知道究竟是什么问题,但如果OP回答我的问题并澄清问题,那么我会回来并更好地尝试解决它。现在,我将把它作为占位符......

查找字母或其他字符的出现位置:

char buf[]="this is the string to search";
int i, count=0, len;
len = strlen(buf);
for(i=0;i<len;i++)
{
    if(buf[i] == 's') count++;
}    

或使用strtok()查找子字符串的出现次数:
不是很好,蛮力方法。
//要搜索的字符串

char str1[]="is";
char str2[]="s";
int count = 0;
char buf[]="this is the string to search";
char *tok;
tok = strtok(buf, str1);
while(tok){
    count++;
    tok = strtok(NULL, str1);
}
tok = strtok(buf, str2);
while(tok){
    count++;
    tok = strtok(NULL, str2);
}  

count应包含“s”的出现总数,+出现的次数为“是”

[编辑]
首先,让我要求对你的问题进行技术澄清,给定A =“AR”,B =“START”,解决方案将是“A”,“R”和“AR”,在这种情况下,所有在第3个发现和B.的第四个字母。这是正确的吗?如果是这样,这很容易。您可以通过对我上面已经完成的一些小修改和补充来做到这一点。如果您对该代码有疑问,如果可以,我很乐意解决这些问题。

第二部分是您真正的问题:搜索效果比 KMP algorithm 更好,或至少与效率相同 - 这才是真正的伎俩。如果选择最佳方法是真正的问题,那么一些谷歌搜索是有序的。因为一旦找到并解决了解决子字符串搜索的最佳方法(效率&gt; = KPM),那么实现将是一组简单的步骤(if you give it enough time),可能,但不一定使用上面使用的一些与C相同的组件。 (指针操作比使用我认为的字符串函数更快。)但这些技术只是实现,应该始终遵循一个好的设计。以下是一些Google搜索,以帮助您开始搜索...(您可能已经访问过其中一些)

Validating KMP
KMP - Can we do better?
KMP - Defined
KMP - Improvements using Fibonacci String

如果您选择了算法并开始实施设计,则会对技术或编码建议有疑问,发布它们。我猜这里有几个人喜欢帮助这么有用的算法。

答案 1 :(得分:0)

如果X是Y中的子字符串,那么X的每个字符必须是Y.所以我们首先遍历X并在数组counts中找到每个字符的计数。

然后,对于count >= 1的每个字符,我们会计算它在Y中出现的次数,这可以在O(n)中轻松完成。

从这里开始,答案应该是组合C(count(Y),count(X))的倍增。

如果在第3次读完你的问题之后我终于明白了。