簡體   English   中英

如何在C中部分比較兩個字符串?

[英]How can I partial compare two strings in C?

假設我有以下內容:

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

如何使用C在該字符串中搜索dummydummy text 有什么簡單的方法可以做到這一點,還是只有強大的字符串操作才能做到? 我所需要做的就是搜索它,並返回一個帶有結果的布爾值。

編輯:
你們圍繞這個話題進行了大討論,並提出了一些算法,我不介意這可能對其他人甚至將來對我都有用。 但是我真正想要的是最簡單的方法,無論時間/空間復雜度如何。 這對我在做什么並不重要。 因此, strstr可以輕松快速地解決我的問題。 我真的必須給我一些標准的C函數速寫表。

標准庫函數是strstr

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

它將指針返回到找到匹配項的字符串中;如果未找到,則返回if (strstr(...))因此,如果您需要的只是一個布爾值,只需測試返回值( if (strstr(...))

如果您想要簡單的東西並且您的字符串不太長,可以使用strstr函數。 但是,如果您的字符串很長,請考慮使用KMP算法,因為它效率更高。

我真的不喜歡Wikipedia的文章,因為那里的實現對我來說有點奇怪(盡管可能是正確的),並且它也誤導了KMP的性能。 我更喜歡此處和Google搜索“ KMP算法”返回的其他網站上給出的實現和說明。

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的絕妙著作《 編程實踐 》中有一個關於strstr()和性能的戰爭故事。


我做了一些實驗-使用James King聖經(4.8 MB)的副本作為純文本,並對其進行內存映射。 對於許多搜索,(MacOS X 10.6.2 / BSD) strstr()比KMP或BM都快。 當字符串足夠長(大約12個以上的字符)時,BM算法最終超過了strstr() 該KMP算法似乎總是要慢得多

德?

  • 很難超越一個好的圖書館。
  • 在合理的英語字符串上,KMP比BM慢得多。

而且我圍繞算法放置的基礎結構可能太沉重了-但是原始代碼中的替代方法是回調機制,這給確定匹配上下文帶來了一些問題。

我將使用strstr (也在此處 )。

我不是要在問題中使用“部分”一詞。 參數(“虛擬”或“虛擬文本”)必須完全匹配,對嗎?

我一直很喜歡Boyer-Moore。 它是O(n),但必須進行設置(即必須預先計算兩個表。)因此,如果要搜索大量文本,或者事先知道搜索字符串,則很好,這樣可以彌補成本桌子的制作。 這也是8位ASCII的最佳選擇。

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

(順便說一句,strstr()有Unicode風格嗎?)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM