ठीक है, इसलिए मैं किसी बेवकूफ की तरह आवाज़ नहीं करता हूं, मैं समस्या / आवश्यकताओं को अधिक स्पष्ट रूप से बताने जा रहा हूं:
- सुई (पैटर्न) और हिस्टैक (खोज करने के लिए पाठ) दोनों सी-स्टाइल अशक्त-समाप्त स्ट्रिंग्स हैं। कोई लंबाई की जानकारी नहीं दी गई है; यदि आवश्यक हो, यह गणना की जानी चाहिए।
- फ़ंक्शन को पहले मैच के लिए एक सूचक लौटना चाहिए, या
NULL
यदि कोई मैच नहीं मिला है। - विफलता के मामलों की अनुमति नहीं है। इसका मतलब है कि गैर-स्थिर (या बड़े स्थिर) भंडारण आवश्यकताओं के साथ किसी भी एल्गोरिथ्म को आवंटन विफलता के लिए एक कमबैक केस की आवश्यकता होगी (और फ़ॉलबैक देखभाल में प्रदर्शन जिससे सबसे खराब स्थिति में योगदान होता है)।
- कार्यान्वयन सी में होना है, हालांकि कोड के बिना एल्गोरिथ्म (या इस तरह के लिंक) का एक अच्छा विवरण भी ठीक है।
... साथ ही "सबसे तेज़" से मेरा क्या मतलब है:
- नियतात्मक
O(n)
जहाँn
= पाताल लंबाई। (लेकिन एल्गोरिदम से विचारों का उपयोग करना संभव हो सकता है जो सामान्य तौर पर होते हैंO(nm)
(उदाहरण के लिए हैश रोलिंग) यदि वे निर्धारकO(n)
परिणाम देने के लिए अधिक मजबूत एल्गोरिथ्म के साथ संयुक्त होते हैं )। - कभी नहीं (औसत रूप से;
if (!needle[1])
आदि के लिए एक जोड़ी घड़ियां ठीक हैं) भोले जानवर बल एल्गोरिथ्म से भी बदतर हैं, खासकर बहुत छोटी सुइयों पर जो सबसे आम मामला है। (बिना शर्त भारी प्रीप्रोसेसिंग ओवरहेड खराब है, जैसा कि संभावित सुइयों की कीमत पर रोग संबंधी सुइयों के लिए रैखिक गुणांक में सुधार करने की कोशिश कर रहा है।) - एक मनमाना सुई और हिस्टैक, तुलनीय या बेहतर प्रदर्शन (50% से अधिक लंबे खोज समय से अधिक) बनाम किसी भी अन्य व्यापक रूप से कार्यान्वित एल्गोरिथ्म को देखते हुए।
- इन स्थितियों के अलावा, मैं "सबसे तेज़" ओपन-एंड की परिभाषा छोड़ रहा हूं। एक अच्छे उत्तर से यह स्पष्ट होना चाहिए कि आप उस दृष्टिकोण पर क्यों विचार कर रहे हैं जो आप "सबसे तेज़" सुझा रहे हैं।
मेरा वर्तमान कार्यान्वयन लगभग 10% धीमे और 8 गुना तेज़ (इनपुट के आधार पर) के बीच ग्लिब्क के टू-वे के कार्यान्वयन से चलता है।
अद्यतन: मेरा वर्तमान इष्टतम एल्गोरिथ्म इस प्रकार है:
- लंबाई 1 की सुइयों के लिए, का उपयोग करें
strchr
। - लंबाई 2-4 की सुइयों के लिए, एक बार में 2-4 बाइट्स की तुलना करने के लिए मशीन शब्दों का उपयोग करें: बिटहिफ्ट्स के साथ 16- या 32-बिट पूर्णांक में प्रीलोड करें और प्रत्येक पुनरावृत्ति में धड़ से पुराने बाइट आउट / नए बाइट्स को साइकिल करें। । हिस्टैक के हर बाइट को एक बार ठीक से पढ़ा जाता है और 0 (स्ट्रिंग के अंत) और एक 16- या 32-बिट की तुलना के खिलाफ एक चेक लगाता है।
- लंबाई> 4 की सुइयों के लिए, खराब शिफ्ट टेबल (जैसे बोयर-मूर) के साथ टू-वे एल्गोरिथ्म का उपयोग करें जो केवल खिड़की के अंतिम बाइट पर लागू होता है। 1kb तालिका को प्रारंभ करने के ओवरहेड से बचने के लिए, जो कि कई मध्यम-लंबाई वाली सुइयों के लिए शुद्ध नुकसान होगा, मैं एक बिट सरणी (32 बाइट्स) को चिह्नित करता हूं जो शिफ्ट तालिका में कौन सी प्रविष्टियां आरंभीकृत होती हैं। बिट्स जो कि परेशान हैं वे बाइट मूल्यों के अनुरूप हैं जो कभी भी सुई में नहीं दिखाई देते हैं, जिसके लिए एक पूर्ण-सुई-लंबाई शिफ्ट संभव है।
मेरे मन में बचे हुए बड़े प्रश्न हैं:
- क्या खराब शिफ्ट टेबल का बेहतर उपयोग करने का कोई तरीका है? बॉयर-मूर पीछे की ओर (दाएं-बाएं) स्कैन करके इसका सबसे अच्छा उपयोग करता है, लेकिन टू-वे को बाएं से दाएं स्कैन की आवश्यकता होती है।
- सामान्य मामले (नो-आउट-ऑफ-मेमोरी या क्वाड्रैटिक प्रदर्शन की स्थिति) के लिए मेरे द्वारा देखे गए केवल दो व्यवहार्य उम्मीदवार एल्गोरिदम ऑर्डर किए गए अक्षर पर दो-तरफ़ा और स्ट्रिंग मिलान हैं । लेकिन क्या आसानी से पता लगाने योग्य मामले हैं जहां विभिन्न एल्गोरिदम इष्टतम होंगे? अंतरिक्ष एल्गोरिदम में निश्चित रूप से कई
O(m)
(जहांm
सुई की लंबाई है) का उपयोगm<100
या तो किया जा सकता है । एल्गोरिदम का उपयोग करना भी संभव होगा जो सबसे खराब स्थिति वाले हैं यदि सुइयों के लिए एक आसान परीक्षण है, जिसमें केवल रैखिक समय की आवश्यकता होती है।
के लिए बोनस अंक:
- क्या आप यह मानकर प्रदर्शन में सुधार कर सकते हैं कि सुई और हिस्टैक दोनों अच्छी तरह से गठित UTF-8 हैं? (अलग-अलग बाइट लंबाई के पात्रों के साथ, अच्छी तरह से गठित-नेस सुई और हिस्टैक के बीच कुछ स्ट्रिंग संरेखण आवश्यकताओं को लगाता है और स्वचालित 2-4 बाइट शिफ्ट की अनुमति देता है जब एक बेमेल हेड बाइट का सामना करना पड़ता है। लेकिन क्या इन बाधाओं से आपको बहुत कुछ मिलता है / क्या परे है। अधिकतम प्रत्यय संगणना, अच्छी प्रत्यय पारियां, आदि पहले से ही आपको विभिन्न एल्गोरिदम के साथ देते हैं?)
नोट: मैं वहां के अधिकांश एल्गोरिदम से अच्छी तरह से वाकिफ हूं, सिर्फ इसलिए नहीं कि वे अभ्यास में कितना अच्छा प्रदर्शन करते हैं। यहाँ एक अच्छा संदर्भ है इसलिए लोग मुझे टिप्पणियों / उत्तरों के रूप में एल्गोरिदम पर संदर्भ नहीं देते हैं: http://www-igm.univ-mlv.fr/~lecroq/string/index.html
strstr
बाद में कुछ और सुधार किया है, इसलिए मैंने वास्तव में आपके द्वारा लिंक किए गए पेपर को ठीक से पढ़ने के लिए इधर-उधर नहीं किया है, लेकिन यह बहुत ही आशाजनक ध्वनि है। आपके वापस न आने के लिए धन्यवाद और खेद।