2012-12-25 14 views
11

मान लीजिए कि मेरे पास एक स्ट्रिंग है और मैं यह जानना चाहता हूं कि कोई विशिष्ट वर्ण (जैसे '|') मौजूद है या नहीं, तो करने के लिए सबसे अच्छी और तेज़ तकनीक क्या है इसलिए? मुझे पता है कि स्ट्रिंग को कार्यान्वयन मिल रहा है। मैं इस से भी तेज कार्यान्वयन के लिए पूछ रहा हूं।खोजें कि किसी स्ट्रिंग में सी ++ (बूस्ट स्वीकृत)

+3

एक 'std :: स्ट्रिंग' संदर्भ के माध्यम से देखो और आप अंत में' find' मिल जाएगा। – chris

+0

आपके द्वारा उपयोग की जाने वाली स्ट्रिंग के "फ़ॉर्म" पर निर्भर करता है। –

+0

कृपया शीर्षक में "सर्वश्रेष्ठ" और "सबसे तेज़" से बचें; पूर्व को लगभग हमेशा से बचा जाना चाहिए क्योंकि यह थोड़ा मूल्य जोड़ता है ("सर्वश्रेष्ठ" तरीका "सर्वश्रेष्ठ" उत्तर में दिया जाएगा), और बाद में तब तक टालना चाहिए जब तक एक विशिष्ट परीक्षण-केस/परिदृश्य नहीं है जहां आम दृष्टिकोण "पर्याप्त तेज़ नहीं हैं" (और इसके लिए * इसकी तुलना करने के लिए पहले कुछ चाहिए *) –

उत्तर

27

उपयोग std::string::find

if (str.find('|') != std::string::npos) 
{ 
    // ... 
} 

वहाँ कुछ भी अधिक कुशल होने की संभावना नहीं है। हे (एन) सबसे अच्छा है जो आप कर सकते हैं। मानक पुस्तकालय कार्यान्वयन काफी अनुकूल होना चाहिए।

0

ऐसा करने का केवल एक ही तरीका है। यह जांचने के लिए कि आप जिस चरित्र को खोज रहे हैं, उसे स्ट्रिंग पर बस फिर से चालू करें। आप string::find फ़ंक्शन का उपयोग कर ऐसा कर सकते हैं, जो एक वर्ण प्राप्त करता है और स्ट्रिंग में होने वाली पहली स्थिति देता है, या मान string::npos यदि मान मौजूद नहीं है। आप std::find का भी उपयोग कर सकते हैं, जो दो इटरेटर, begin और end और एक महत्वपूर्ण मान 'के' प्राप्त करता है और , या में k श्रेणी में के पहले घटना पर इंगित करने वाला एक पुनरावर्तक देता है। और निश्चित रूप से, आप पा समारोह अपने आप से, लागू कर सकते हैं इस तरह:

string::size_type pos=string::npos; 
for(string::size_type i=0; i<s.size(); ++i) { 
    if(s[i] == key) { 
    pos=i; 
    break; 
    } 
} 
if(pos != string::npos) { 
    // key was found 
} else { 
    // not found 
} 

या इस:

string::iterator pos=s.end(); 
for(string::iterator i=s.begin(); i!=s.end(); ++i) { 
    if(*i == key) { 
    pos=i; 
    break; 
    } 
} 
if(pos != s.end()) { 
    // found 
} else { 
    // not found 
} 

अधिक std::string::find और std::find के बारे में:

0

अपने बयान को देखते हुए कि आप स्ट्रिंग :: खोज से कुछ तेज़ी से चाहते हैं, केवल एक चीज जिसे मैं सोच सकता हूं वह एक वर्ग बनाना होगा जिसमें अत्यधिक अनुकूलित असाइनमेंट ऑपरेटर थे जो स्ट्रिंग के प्रत्येक अपडेट पर एक आंतरिक तालिका को अपडेट करते थे जिसमें निहित था प्रत्येक संभावित चरित्र की स्ट्रिंग में पहली स्थिति (एक चौड़ी स्ट्रिंग के लिए 256, एक विस्तृत स्ट्रिंग के लिए 65536 (?))। गैर-कॉन्स ऑपरेशंस में जोड़े गए बहुत जटिलता के खर्च पर ओ (1) लुकअप है।

1

एक और तरीका इसी c_str स्ट्रिंग पर strchr समारोह का उपयोग करने के लिए है:

if(strchr(str.c_str(), '|')) 
{ 
    \\found 
} 

सुनिश्चित नहीं हैं कि यह कैसे गति हालांकि के मामले में मिल एसटीडी तुलना ...

पाया की स्थिति चरित्र

size_t pos = strchr(str.c_str(),'|') - str.c_str(); 
+0

का उल्लेख न करने के लिए क्षमा करें http://www.cplusplus.com/reference/cstring/strchr/ 2 तर्क – Peter

+0

लेता है "यदि चरित्र नहीं मिला है, तो फ़ंक्शन एक शून्य सूचक देता है"। तो आपके उदाहरण में, आप उस मामले में एक पूर्ण सूचक से घटा रहे हैं। सूचक ओवरफ्लो यूबी है। – namezero

+0

@namezero यही कारण है कि हम घटाव द्वारा pos प्राप्त करने का प्रयास करने से पहले एक कथन के साथ शुरू करते हैं, इसलिए यदि चरित्र नहीं मिला है तो हम pos प्राप्त करने का प्रयास नहीं करते हैं। – afakih

1

टॉम टैनर का उत्तर जोड़ना। यदि आप कोई प्राथमिकता गणना नहीं करना चाहते हैं तो आप ओ (एन) पर फंस जाएंगे, यानी आप जिस स्ट्रिंग में खोज रहे हैं और समय की खपत के बीच एक रैखिक सहसंबंध है। टॉम ने बूलियन के एक सरणी (या वेक्टर) को स्थापित करने का सुझाव दिया जो इंगित करता है कि कोई निश्चित चरित्र हुआ है या नहीं। स्ट्रिंग को इंडेक्स करने के लिए इसे ओ (एन) की आवश्यकता होगी, लेकिन फिर यदि आप शामिल हैं तो आप ओ (1) (निरंतर समय) में किसी भी वर्ण की जांच कर सकते हैं। इस दृष्टिकोण के साथ नकारात्मकता यह है कि आपको बहुत मेमोरी की आवश्यकता होगी (एक बार जब आप तय करते हैं कि आपको यूनिकोड का समर्थन करने की आवश्यकता है)।

समझौता के रूप में आप एक std :: सेट या इसी तरह का उपयोग कर सकते हैं, केवल उन वर्णों को संग्रहीत कर सकते हैं जो वास्तव में आपके इनपुट स्ट्रिंग में मौजूद हैं।मेमोरी खपत स्ट्रिंग में विभिन्न वर्णों की संख्या के संबंध में रैखिक होगी लेकिन लुकअप ओ (लॉग एन) होगा, यानी समय में लॉगरिदमिक होगा।

बेशक आपको माप/प्रोफाइल करना चाहिए और फिर यहां समझाएं कि आप वास्तव में किस मामले का उपयोग कर रहे हैं। जब तक आप ऐसा नहीं कर लेते, तब तक समझने और पढ़ने के लिए सबसे आसान क्या है।

1

this source अनुभवजन्य विजुअल स्टूडियो 2013 के साथ किया परीक्षण से पता चलता है कि संकलक strchr दिनचर्या के बारे में 2x तेजी से std :: स्ट्रिंग :: कार्यान्वयन लगता है।

+0

निश्चित रूप से, यदि यह काम करता है। –

0

आप इस कोशिश कर सकते हैं:

string s1 = "Hello"; 
    string s2 = "el"; 
    if(strstr(s1.c_str(),s2.c_str())) 
    { 
    cout << " S1 Contains S2"; 
    }