2010-03-27 68 views
1

比方說,我有以下內容:如何部分比較C中的兩個字符串?

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

如何尋找在用C該字符串dummydummy text?有沒有簡單的方法來做到這一點,或只有強大的字符串操作?我需要的只是搜索它並返回一個布爾值和結果。

編輯:
你們創造了圍繞這一話題的大討論,並提出一些算法,我不介意的原因,這可能是對別人有用的,甚至我的未來。但是,我真正想要的是最簡單的方法,無論時間/空間的複雜性如何。這對我在做什麼並不重要。所以,strstr輕鬆快速地解決了我的問題。我真的得給我一些標準的C函數chet表。

回答

5

這個標準庫函數是strstr

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

它返回一個指針到那裏比賽被發現,或NULL,如果它不是字符串 - 所以,如果你需要的是一個布爾值,只是測試的返回值(if (strstr(...))

+0

而且,的strstr()是POSIX - 是啊! http://www.opengroup.org/onlinepubs/9699919799/ – 2010-03-27 20:19:05

+0

@Kevin:不在C標準庫中,它的意思是它也在POSIX中? (POSIX規定,其目標之一是 「與ISO/IEC 9899對齊:1999標準,包括ISO/IEC 9899:1999/Cor.2:2004(E)」) – 2010-03-27 21:21:57

+0

@邁克爾:我認爲你是正確的,在至少就「string.h」的內容而言。我只是試圖強化Jefromi輕輕推動的「*標準*庫功能」概念,爲POSIX帶來歡呼,這是一個20年以上的習慣,難以打破! :) – 2010-03-27 23:28:58

2

,如果你想簡單的東西,你的字符串不是太長,你可以使用strstr功能。如果你的字符串很長但是,考慮KMP算法,因爲它是一個很大的高效。

我不太喜歡維基百科的文章,因爲那裏的實現看起來有點奇怪(雖然它可能是正確的),並且它也誤導了KMP的性能。我更喜歡here和谷歌搜索返回的其他網站上的實施和描述「KMP算法」。

+0

這在某些情況下效率更高。來自維基百科文章引用的鏈接:「請注意,在實踐中,KMP算法不擅長於在自然語言文本中進行搜索,因爲當模式的第一部分實際上匹配文本的一部分時,它只能跳過字符。偶爾會發生在自然語言文本中。「 – Cascabel 2010-03-27 20:14:51

+1

據我所知,'strstr'函數的時間複雜度是'O(NM)',而KMP的複雜度是'O(N + M)',所以即使有些情況下它的行爲並不是最好的儘可能地,它仍然不會達到二次時間,所以它應該總是比'strstr'更快。 – IVlad 2010-03-27 20:17:02

+1

@IVlad:當然,你說的很複雜。我沒有做過任何真正的分析,但這裏是揮之不去的論點。實際上在那些大O的前面有常數,而KMP的是更大的,因爲它所做的所有額外的工作。如果KMP不會跳過太多(這可能不是自然語言文本),但它可能在一組自然語言搜索中表現更差,儘管它在所有字符串中都更好。這些都是*平均*複雜性。別擔心,你有我的贊成,只是想指出收益不一定像聽起來那麼大。 – Cascabel 2010-03-27 20:26:08

0

我會用strstr(也here)。

我不是關於在問題中使用「partial」這個詞。參數(「虛擬」或「虛擬文本」)必須完全匹配,對吧?

0

我一直很喜歡Boyer-Moore,我自己。它是O(n),但必須設置(即,兩個表必須預先計算)。因此,如果要搜索大量文本或搜索字符串是事先知道的,這樣做很好,從而彌補成本建立桌子。對於8位ASCII也是最好的。

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

(順便說一句,有沒有的strstr的Unicode的味道()?)

+0

如果needle和乾草堆使用相同的編碼(並且該編碼與ASCII兼容,即UTF-8),則不需要使用unicode版本的strstr。它將字節比較每個元素。當然,它不會做類似於e或é的花式東西......如果您需要高級的東西,Glib具有utf8字符串實用函數:http://library.gnome.org/devel/glib/2.24/glib -Unicode-Manipulation.html – 2010-03-27 20:54:18

+0

@Isak:不完全正確 - 由於基本字符中的NUL字節,'strstr()'在UTF-16上不能正常工作。這不同於你通常使用'wchar_t'的事實 - 推測是'wcsstr()'。對於UTF-8,基本的'strstr()'工作正常。 – 2010-03-27 21:21:36

+0

是的,你是正確的喬納森...這就是我想說的「ascii兼容」..但它是值得clairifying無論如何 – 2010-03-28 10:13:50

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()完成等的環境,你必須能夠按需切換內存分配器。您可以忽略兩個typedef和相應的函數;當然,默認設置是使用malloc()free()

基本KMP算法的代碼來自上方部位 - 但進行了修改,允許我設置搜索字符串一次,然後搜索多個目標串等聯繫我(見我的個人資料)的源代碼。我也得到了Boyer-Moore代碼的類似結構(相同的原始源代碼),以及不區分大小寫的Boyer-Moore代碼。

關於strstr()有一個很好的戰爭故事,並在Kernighan和派克的優秀書籍「The Practice of Programming」中表現出色。


我做了一些實驗 - 利用國王詹姆斯聖經(4.8 MB)的副本作爲純文本,並且內存映射這一點。對於許多搜索,(MacOS X 10.6.2/BSD)strstr()比KMP或BM更快。當琴絃長得足夠長時(大約12個以上的字符),則BM算法最終超過了strstr()。 KMP算法似乎總是比較慢很多

道德?

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

而我在這些算法周圍放置的基礎設施可能太重了 - 但原始代碼中的替代方法是回調機制,它在確定匹配上下文時存在一些問題。