假设我有以下内容:
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
如何使用C在该字符串中搜索dummy
或dummy text
?有没有简单的方法来做或只有强大的字符串操作?我只需要搜索它并返回一个包含结果的布尔值。
修改
你们围绕这个主题创建了一个大讨论,并提出了一些算法,我不介意,因为这可能对其他人,甚至将来我都有用。但无论时间/空间的复杂性如何,我真正想要的是最简单的方法。这对我正在做的事情并不重要。因此,strstr
可以轻松快速地解决我的问题。我真的得给我一些标准的C函数chet表。
答案 0 :(得分:5)
标准库函数是strstr:
char *strstr(const char *haystack, const char *needle);
它返回一个指向发现匹配的字符串的指针,如果不是则返回NULL - 所以如果你需要的只是一个布尔值,只需测试返回值(if (strstr(...))
。
答案 1 :(得分:2)
如果您想要简单且字符串不会太长,您可以使用strstr功能。但是,如果您的字符串很长,请考虑使用KMP算法,因为它效率更高。
我真的不喜欢维基百科的文章,因为那里的实现看起来有些奇怪(尽管它可能是正确的),而且它也误导了KMP的性能。我更喜欢here给出的实施和说明以及Google搜索“KMP算法”返回的其他网站。
答案 2 :(得分:2)
在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()
等进行内存分配的环境中工作,并且你必须能够切换内存按需分配器。你可以忽略两个typedef和相应的函数;当然,默认设置是使用malloc()
和free()
。
基本的KMP算法代码来自上面的网站 - 但是经过修改以允许我设置一次搜索字符串,然后搜索多个目标字符串等。联系我(参见我的个人资料)获取源代码。我也有类似Boyer-Moore代码的结构(相同的原始资源),以及一个不区分大小写的Boyer-Moore代码。
在Kernighan和Pike的优秀书籍“The Practice of Programming”中有一篇关于strstr()
和表演的好战故事。
我做了一些实验 - 使用King James Bible(4.8 MB)的副本作为纯文本和内存映射。对于许多搜索,(MacOS X 10.6.2 / BSD)strstr()
比KMP或BM快。当字符串长得足够长(大约12个字符)时,BM算法最终超过strstr()
。 KMP算法似乎总是多慢。
德?
我在算法周围设置的基础设施可能过于繁重 - 但原始代码中的替代方案是回调机制,这为确定匹配的上下文提出了一些问题。
答案 3 :(得分:0)
答案 4 :(得分:0)
我一直很喜欢Boyer-Moore。它是O(n),但必须设置(即,必须预先计算两个表。)因此,如果要搜索大量文本,或者提前知道搜索字符串,这样做是好的,从而弥补了成本建立表格。它也适用于8位ASCII。
[http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm]
(顺便说一句,是否有strstr()的Unicode风格?)