如何在C中部分比较两个字符串?

时间:2010-03-27 20:07:38

标签: c string string-comparison

假设我有以下内容:

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

如何使用C在该字符串中搜索dummydummy text?有没有简单的方法来做或只有强大的字符串操作?我只需要搜索它并返回一个包含结果的布尔值。

修改
你们围绕这个主题创建了一个大讨论,并提出了一些算法,我不介意,因为这可能对其他人,甚至将来我都有用。但无论时间/空间的复杂性如何,我真正想要的是最简单的方法。这对我正在做的事情并不重要。因此,strstr可以轻松快速地解决我的问题。我真的得给我一些标准的C函数chet表。

5 个答案:

答案 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算法似乎总是慢。

德?

  • 很难超越一个好的图书馆。
  • KMP在合理的英语字符串上比BM慢得多。

我在算法周围设置的基础设施可能过于繁重 - 但原始代码中的替代方案是回调机制,这为确定匹配的上下文提出了一些问题。

答案 3 :(得分:0)

我会使用strstr(也是here)。

我不是在问题中使用“部分”这个词。参数(“虚拟”或“虚拟文本”)必须完全匹配,对吧?

答案 4 :(得分:0)

我一直很喜欢Boyer-Moore。它是O(n),但必须设置(即,必须预先计算两个表。)因此,如果要搜索大量文本,或者提前知道搜索字符串,这样做是好的,从而弥补了成本建立表格。它也适用于8位ASCII。

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

(顺便说一句,是否有strstr()的Unicode风格?)