繁体   English   中英

计数子串的出现

[英]counting of the occurrence of substrings

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

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

示例如下:在字符串Y=ABCDBFGHIJ搜索X=AB Y=ABCDBFGHIJ

答案是2:第一个A和第二个B,以及第一个A和第5个B。

我知道我们可以生成长字符串的所有排列(将是N!长度N字符串Y ),并使用KMP算法搜索/计算YX的出现。

我们可以做得更好吗?

我尝试解决的原始问题如下:假设我们有一个大小为r乘c的大矩阵M(r和c在10000的范围内)。 给定一个大小为a x b的小矩阵P(a和b在10的范围内)。 求出M的行和b列的不同选择的总数(这将为我们提供一个乘以b的“子矩阵” H),以便对H的行和列进行排列,从而得到一个与P匹配的矩阵。

我认为一旦我能解决一维问题,二维就可以解决。

经过研究,我发现这是一个子图同构问题,并且是NP难的。 有一些算法可以有效地解决这个问题。 一个人可以用谷歌搜索并看到许多关于此的论文。

阅读完然后重新阅读问题(按照@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);
}  

计数应包含出现次数“ s”的总数,以及出现次数“ is”的总数

[编辑]
首先,让我要求对您的问题进行技术澄清,给定A =“ AR”,B =“ START”,解决方案将是“ A”,“ R”和“ AR”,在这种情况下,所有解决方案均在第三和B的第4个字母。对吗? 如果是这样,那很容易。 您可以通过对我上面已经做的事情进行一些小的修改和添加来做到这一点。 如果您对此代码有疑问,请尽可能解决。

第二部分是您真正的问题:搜索的效率优于KMP算法 ,或者至少具有与KMP算法相同的效率- 这才是真正的窍门。 如果选择最佳方法是真正的问题,那么应该进行一些Google搜索。 因为一旦找到并确定解决子字符串搜索的最佳方法(效率> = KPM),那么该实现将是一组简单的步骤( 如果您有足够的时间进行 ),可能但不一定使用上面使用的C的某些相同组件。 (指针操纵比使用我认为的字符串函数要快。)但是这些技术只是实现,应始终遵循良好的设计。 以下是一些Google搜索,可帮助您开始搜索...(您可能已经去过其中一些)

验证KMP
KMP-我们可以做得更好吗?
KMP-定义
KMP-使用斐波那契弦的改进

一旦选择了算法并开始实施设计,就对技术或编码建议有疑问,请发布它们。 我的猜测是,这里有几个人会喜欢这种有用的算法。

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

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

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

如果在第三次阅读您的问题后,我终于正确理解了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM