Найти счетчик подстроки в строке
Мне нужно найти счетчик подстроки в строке с использованием языка C.
Я использую функцию strstr
, но она находит только первое вхождение.
Мое представление об алгоритме - это что-то вроде поиска в строке, а strstr
не возвращает null и
подстроить основную строку в каждом цикле.
Мой вопрос: как это сделать?
Ответы
Ответ 1
Вы можете сделать что-то вроде
int count = 0;
const char *tmp = myString;
while(tmp = strstr(tmp, string2find))
{
count++;
tmp++;
}
То есть, когда вы получите результат, снова начните поиск в следующей позиции строки.
strstr() работает не только с начала строки, но и с любой позиции.
Ответ 2
Должны ли уже обработанные части строки использоваться или нет?
Например, каков foooo
ответ для случая поиска oo
в foooo
, 2 или 3?
-
Если последнее (мы допускаем перекрытие подстрок, а ответ равен трем), то Иоахим Исакссон предложил правильный код.
-
Если мы ищем разные подстроки (ответ должен быть два), то посмотрите код ниже (и онлайн-пример здесь):
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++;
}
Ответ 3
ИСПОЛЬЗУЙТЕ 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.
}
Ответ 4
Результаты могут отличаться в зависимости от того, разрешаете ли вы перекрытие или нет:
// 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
Ответ 5
/*
* C Program To Count the Occurence of a Substring in String
*/
#include <stdio.h>
#include <string.h>
char str[100], sub[100];
int count = 0, count1 = 0;
void main()
{
int i, j, l, l1, l2;
printf("\nEnter a string : ");
scanf("%[^\n]s", str);
l1 = strlen(str);
printf("\nEnter a substring : ");
scanf(" %[^\n]s", sub);
l2 = strlen(sub);
for (i = 0; i < l1;)
{
j = 0;
count = 0;
while ((str[i] == sub[j]))
{
count++;
i++;
j++;
}
if (count == l2)
{
count1++;
count = 0;
}
else
i++;
}
printf("%s occurs %d times in %s", sub, count1, str);
}