C言語を使用して、文字列内の部分文字列の数を見つける必要があります。私は関数 strstr
を使用していますが、最初の出現のみを検出します。
アルゴリズムについての私の考えは、strstr
がnullを返さず、各ループでメイン文字列をサブストリング化する一方で、文字列を検索するようなものです。私の質問はそれを行う方法ですか?
あなたは次のようなことをすることができます
int count = 0;
const char *tmp = myString;
while(tmp = strstr(tmp, string2find))
{
count++;
tmp++;
}
つまり、結果が得られたら、文字列の次の位置から再度検索を開始します。
strstr()は、文字列の先頭からだけでなく、どの位置からも機能します。
文字列の処理済みの部分を消費する必要があるかどうか。
たとえば、oo
、2または3でfoooo
を検索する場合の予想回答は何ですか?
後者(我々が部分文字列のオーバーラップを許可で、答えが3の場合)、Joachim Isaksson 推奨 正しいコード。
私たちが別個の部分文字列を検索する場合(答えは2つである必要があります)、以下のコードを参照してください(そしてオンラインの例 ここ ) :
char *str = "This is a simple string";
char *what = "is";
int what_len = strlen(what);
int count = 0;
char *where = str;
if (what_len)
while ((where = strstr(where, what))) {
where += what_len;
count++;
}
USE [〜#〜] kmp [〜#〜] そしてO(n)でそれを行うことができます
int fail[LEN+1];
char s[LEN];
void getfail()
{
//f[i+1]= max({j|s[i-j+1,i]=s[0,j-1],j!=i+1})
//the correctness can be proved by induction
for(int i=0,j=fail[0]=-1;s[i];i++)
{
while(j>=0&&s[j]!=s[i]) j=fail[j];
fail[i+1]=++j;
if (s[i+1]==s[fail[i+1]]) fail[i+1]=fail[fail[i+1]];//optimizing fail[]
}
}
int kmp(char *t)// String s is pattern and String t is text!
{
int cnt=0;
for(int i=0,j=0;t.s[i];i++)
{
while(j>=0&&t.s[i]!=s[j]) j=fail[j];
if (!s[++j])
{
j=fail[j];
cnt++;
}
}
return cnt;// how many times s appeared in t.
}
結果は、オーバーラップを許可するかどうかによって異なります。
// gcc -std=c99
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
static int
count_substr(const char *str, const char* substr, bool overlap) {
if (strlen(substr) == 0) return -1; // forbid empty substr
int count = 0;
int increment = overlap ? 1 : strlen(substr);
for (char* s = (char*)str; (s = strstr(s, substr)); s += increment)
++count;
return count;
}
int main() {
char *substrs[] = {"a", "aa", "aaa", "b", "", NULL };
for (char** s = substrs; *s != NULL; ++s)
printf("'%s' -> %d, no overlap: %d\n", *s, count_substr("aaaaa", *s, true),
count_substr("aaaaa", *s, false));
}
'a' -> 5, no overlap: 5
'aa' -> 4, no overlap: 2
'aaa' -> 3, no overlap: 1
'b' -> 0, no overlap: 0
'' -> -1, no overlap: -1
s
およびsubstr
がnullでも空でもないと仮定します。
/* #times substr appears in s, no overlaps */
int nappear(const char *s, const char *substr)
{
int n = 0;
const char *p = s;
size_t lenSubstr = strlen(substr);
while (*p) {
if (memcmp(p, substr, lenSubstr) == 0) {
++n;
p += lenSubstr;
} else
++p;
}
return n;
}