2010-03-27 2 views
1

Скажем, у меня есть следующее содержание:Как я могу частично сравнить две строки в C?

Lorem Ipsum is simply dummy text of the printing and typesetting industry. 

Как искать dummy или dummy text в этой строке, используя C? Есть ли простой способ сделать это или только при сильных манипуляциях с строкой? Все, что мне нужно - это искать его и возвращать логическое значение с результатом.

EDIT:
Вы, ребята создали большую дискуссию вокруг этой темы и предложил несколько алгоритмов, и я не против того, что причина этого может быть полезным для кого-то еще, или даже меня в будущем. Но то, что я действительно хотел, было самым простым способом сделать это, независимо от сложности времени и пространства. Это не имеет большого значения для того, что я делаю. Итак, strstr легко и быстро исправил мою проблему. Мне действительно нужно получить мне стандартный набор функций CH.

ответ

5

Стандартная библиотека функций для этого strstr:

char *strstr(const char *haystack, const char *needle); 

возвращает указатель на строку, где матч был найден, или NULL, если оно не было - так что, если все, что вам нужно, это логическое значение, просто проверить возвращаемое значение (if (strstr(...)).

+0

И, strstr() - POSIX - да! http://www.opengroup.org/onlinepubs/9699919799/ –

+0

@Kevin: не находится ли в стандартной библиотеке C, в значительной степени означает, что это также в POSIX? (POSIX заявляет, что одной из целей является «согласование со стандартом ISO/IEC 9899: 1999, включая ISO/IEC 9899: 1999/Cor.2: 2004 (E)») –

+0

@ Майкл: Я думаю, вы правы, что касается содержания «string.h». Я просто пытался укрепить концепцию «стандартной функции библиотеки», которую Джефоми мягко подталкивал, а приветствие для POSIX - это 20-летняя привычка, которую трудно сломать! :) –

2

вы можете использовать функцию strstr, если вы хотите что-то простое и ваши строки не слишком долго. Если ваши строки очень долго, однако, рассмотрим алгоритм KMP, так как это намного больше

Мне не очень нравится статья в Википедии, так как реализация выглядит немного странно для меня (хотя это, вероятно, правильно), и это также вводит в заблуждение о производительности KMP. Я предпочитаю реализацию и описание, данное here, а также на других сайтах, которые были возвращены поиском Google для «алгоритма KMP».

+0

Это намного эффективнее ... в некоторых случаях. Цитата из статьи википедии, которую вы связали: «Обратите внимание, что на практике алгоритм KMP не подходит для поиска в текстах на естественном языке, потому что он может пропускать символы только тогда, когда первая часть шаблона фактически соответствует части текста. иногда случается только в текстах на естественном языке ». – Cascabel

+1

Насколько мне известно, сложность времени функции 'strstr' - это« O (NM) », а сложность KMP -« O (N + M) », поэтому даже если есть случаи, когда она не ведет себя как лучше насколько это возможно, он все равно никогда не достигнет квадратичного времени, поэтому он всегда должен быть быстрее, чем 'strstr'. – IVlad

+1

@IVlad: Конечно, вы правы в сложностях. Я не делал никакого реального анализа, но вот аргумент, размахивающий руками. На самом деле существуют константы перед этими большими O, а KMP больше, из-за всей дополнительной работы, которую он делает. Если KMP не сможет пропускать много (что, вероятно, не в тексте на естественном языке), это может быть хуже для набора естественных поисков языка, несмотря на то, что он лучше всех строк. Это * средняя * сложность.Не волнуйтесь, у вас есть мой верхний план, просто пытаясь указать, что выигрыши не так велики, как они звучат. – Cascabel

0

Я бы использовал strstr (также here).

Я не говорю об использовании слова «частичный» в вопросе. Аргумент («фиктивный» или «фиктивный текст») должен быть полностью согласован, не так ли?

0

Мне всегда нравился Бойер-Мур. Это O (n), но должно быть настроено (т. Е. Две таблицы должны быть предварительно вычислены.) Таким образом, хорошо, если много текста нужно искать, или строки поиска известны заранее, что компенсирует стоимость построения таблиц. Он также подходит для 8-битного ASCII.

[http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm]

(Кстати, есть вкус Юникод strstr()?)

+0

вы не используете юникодную версию strstr, если игла и стог сена находятся в одной кодировке (и эта кодировка совместима с ASCII, то есть UTF-8). Байт сравнивает каждый элемент. Конечно, он не будет делать ничего необычного, как приравнивание è с помощью e или é ... Glib имеет utf8 функции строки, если вам нужны передовые вещи: http://library.gnome.org/devel/glib/2.24/glib -Unicode-Manipulation.html –

+0

@Isak: не совсем верно - 'strstr()' не будет работать хорошо на UTF-16 из-за NUL-байтов в основных символах. Это не зависит от того, что вы обычно используете 'wchar_t' для этого - и предположительно' wcsstr() '. Однако для UTF-8 основной 'strstr()' отлично работает. –

+0

Да, вы правы jonathan ... вот что я пытался сказать «совместим с ascii» .. но все равно стоить clairifying –

1

Там в обширном обсуждение большого числа алгоритмов строкового поиска по http://www-igm.univ-mlv.fr/~lecroq/string/ с иллюстративным кодом C и ссылкой.

Существует обсуждение одного набора комментариев о стоимости алгоритмов. Один из моментов, который следует учитывать, заключается в том, что если вы можете амортизировать затраты на установку по многим вызовам функции поиска, то высокопроизводительные алгоритмы могут принести вам огромную пользу. Если вы все время будете искать разные строки, это сложнее выиграть.

У меня есть версия алгоритма KMP (Knuth-Morris-Pratt), упакованная для многократного повторного использования одной и той же строки поиска.Заголовок:

/* 
@(#)File:   $RCSfile: kmp.h,v $ 
@(#)Version:  $Revision: 1.4 $ 
@(#)Last changed: $Date: 2008/02/02 05:49:34 $ 
@(#)Purpose:  Knuth-Morris-Pratt Search Algorithm 
@(#)Author:   J Leffler 
@(#)Copyright:  (C) JLSS 2005,2008 
@(#)Product:  :PRODUCT: 
*/ 

#ifndef KMP_H 
#define KMP_H 

#include <stddef.h> /* size_t */ 

typedef struct kmp_control kmp_control; 

/* 
** To set up a search (to repeatedly look for the same search string in 
** multiple scan strings), use kmp_setsearch(). To start a search on a 
** new scan string, use kmp_settarget(). To find the next match of a 
** given search string in a given target string, use kmp_search(). Note 
** that kmp_setsearch() and kmp_settarget() do not copy the data in the 
** source and target strings; the pointers must remain valid You can 
** copy kmp_control structures for reuse if desired. 
*/ 
typedef void *(*kmp_malloc)(size_t nbytes); 
typedef void (*kmp_free)(void *data); 

extern kmp_control *kmp_setsearch(const char *search, size_t schlen); 
extern void kmp_settarget(kmp_control *ctrl, const char *target, size_t tgtlen); 
extern const char *kmp_search(kmp_control *ctrl); 
extern void kmp_release(kmp_control *ctrl); 
extern void kmp_setalloc(kmp_malloc mem_alloc, kmp_free mem_free); 

#endif /* KMP_H */ 

Будучи в состоянии определить функции распределения памяти является немного необычным - но мой код часто работает в среде, где распределение памяти не делается с помощью стандартного malloc() и так далее, и вы должны быть в состоянии для переключения распределителя памяти по требованию. Вы можете игнорировать два typedefs и соответствующую функцию; по умолчанию, конечно, использовать malloc() и free().

Основной код алгоритма KMP приведен с сайта выше, но был изменен, чтобы я мог задать строку поиска один раз, а затем выполнить поиск нескольких целевых строк и т. Д. Свяжитесь со мной (см. Мой профиль) для исходного кода. У меня есть аналогичная структура для кода Бойер-Мура тоже (тот же исходный источник), а также нечувствительный к регистру код Бойер-Мура.

Есть хорошая история войны о strstr() и исполнении в отличной книге Кернигана и Пайка «The Practice of Programming».


Я сделал некоторые эксперименты - используя копию Библии короля Джеймса (4,8 MB) как обычный текст, и память отображения этого. Для многих поисков (MacOS X 10.6.2/BSD) strstr() был быстрее, чем KMP или BM. Когда строки росли достаточно долго (примерно 12+ символов), тогда алгоритм BM, наконец, опережал strstr(). Алгоритм KMP всегда казался намного медленнее.

Мораль?

  • Трудно выйти из хорошей библиотеки.
  • KMP намного медленнее BM на правдоподобных строках английского языка.

И инфраструктура, которую я устанавливаю вокруг алгоритмов, может быть слишком тяжелой, но альтернатива в исходном коде является механизмом обратного вызова, что создает некоторые проблемы для определения контекста совпадений.

Смежные вопросы