2011-03-20 23 views
5

मेरी समस्या नीचे दिए गए धागे के समान है, मैं दिए गए उत्तरों को समझने के लिए संघर्ष कर रहा हूं, या बल्कि मेरा कोड काम नहीं करना चाहिए क्योंकि यह केवल इनपुट इटरेटर्स का उपयोग करता है .. लेकिन मेरा func काम करता है और std :: खोज के समान व्यवहार करता है .. इसलिए मैं नुकसान में हूं और ठीक से समझने के बिना आगे बढ़ने के लिए घृणा करता हूं ... शायद अगर कोई ऐसा इनपुट सुझा सकता है जो मेरे फ़ंक्शन को तोड़ देगा लेकिन std ::क्यों std :: खोज को आगे बढ़ने की आवश्यकता है

नहीं Why do I need a Forward Iterator to implement my customized std::search से

:

मैं किताब "त्वरित सी ++" कोएनिग & मू से पढ़ रहा हूँ।

व्यायाम 8-2 मुझ पर लागू करने के लिए पूछना मेरी < एल्गोरिथ्म > और < सांख्यिक > से कुछ templatized कार्यों के मालिक हैं और को इटरेटर किस तरह मेरी कार्यान्वयन की आवश्यकता होती है निर्दिष्ट करें।

std :: search, को लागू करने का प्रयास करते समय मैंने निर्धारित किया कि मुझे केवल "इनपुट" इटरेटर की आवश्यकता है।

हालांकि, कार्यान्वयन एसटीडी की को देख :: मेरी संकलक के साथ स्थापित खोज करते हैं, मैं देख सकता हूँ कि वे "आगे" iterators का उपयोग करें, लेकिन मैं क्यों समझ में नहीं कर सकते हैं, क्योंकि कोई लिखने के लिए जरूरत नहीं है, केवल पढ़ने के लिए, और इनपुट इटरेटर आवश्यकता को पूरा करते हैं।

क्या कोई यहां मुझे समझने में मदद कर सकता है, कृपया? std :: खोज को लागू करने के लिए मुझे "आगे" इटरेटर का उपयोग करने की आवश्यकता क्यों होगी?

अग्रिम धन्यवाद।

myfunction:

template <class In> 
In search( In begin, In end, In begin2, In end2) 
{ 
    In found ;      // iter: 1st element in pattern match(in content) 
    In pattern_begin = begin2 ;  // iter: 1st element in search pattern. 
    int flag = 0 ;     // flag: partial match found? 

    // search content for pattern 
    while ( begin < end ) { 

     // if pattern-match fails ..reset vars 
     // & continue searching remaining content/elements 
     if (*begin != *begin2) { 

      In ret ;      
      begin2 = pattern_begin ; 
      flag = 0 ; 
      begin++ ; 


     } else { 
      // compare next element in pattern with next element in content. 
      // if: 1st element of 'pattern' is found, store iter to it's pos 
      // ..then if entire pattern is found, we can ret an iter to where it starts 
      if (flag == 0) { 
       found = begin ; 
       flag = 1 ; 
      } 
      // inc iters to compare next elements in partial match 
      begin++ ; 
      begin2++ ; 
     } 

     // if: iter is 1-past end of search pattern 
     // then entire pattern has been found 
     // return the iter to where it starts 
     if(begin2 == end2) { return found ; } 

    } 

    // end of content reached, no complete pattern found 
    // begin should? equal an iter 1-past the end of content 
    return begin ; 
} 

चालक:

///* // Driver: custom::search( b, e, b2, e2 ) 
#include <string> 
#include <vector> 
#include <iostream> 
//#include <algorithm> 
#include "library_algorithms.h" 

int main() { 

    // init string test 
    std::string content = "fo The fox foxu jumped foxe foxy " ; 
    std::string search_pattern = "foxy" ; 

    // func test on string 
    std::string::iterator ret_iter = 
    custom::search( content.begin(), content.end(), search_pattern.begin(), search_pattern.end() ) ; 
    //std::search( content.begin(), content.end(), search_pattern.begin(), search_pattern.end() ) ; 

    // output 
    if ( ret_iter != content.end() ) { 

     std::cout << std::endl << std::endl << search_pattern << ": found at position: " << int( ret_iter - content.begin() ) << std::endl; 

    } else { 

     std::cout << std::endl << std::endl << search_pattern << ": ...not found" << std::endl; 
    } 




    // Init vec test: 
    // create content values in range: 10 20 30 <......> 9970 9980 9990 
    std::vector<int> myvector; 
    for (int i=1; i<1000; i++) myvector.push_back(i*10); 

    // create pattern values to search for 
    std::vector<int> pattern ; 
    pattern.push_back(3730) ; 
    pattern.push_back(3740) ; 
    pattern.push_back(3750) ; 
    pattern.push_back(3760) ; 

    // test: func on vector<int> 
    std::vector<int>::iterator it; 
    it = custom::search ( myvector.begin(), myvector.end(), pattern.begin(), pattern.end()); 

    // output 
    if (it!=myvector.end()) 
    std::cout << std::endl << std::endl << "pattern found at position " << int(it-myvector.begin()) << std::endl; 
    else 
    std::cout << std::endl << std::endl << "pattern not found" << std::endl; 





    return 0 ; 

} 

उत्तर

11

आप गलत समझा गया है क्या एक इनपुट इटरेटर कर सकते हैं।

आप एक इनपुट इटरेटर को "सेव" या कॉपी नहीं कर सकते हैं। यह आपको एक बार अनुक्रम को पार करने की अनुमति देता है। दूसरे शब्दों में, यह पंक्ति, दूसरों के बीच, टूट जाएगी: begin2 = pattern_begin

एक इनपुट इटरेटर कुछ ऐसा प्रतिनिधित्व कर सकता है जिसे आप नेटवर्क एडाप्टर से प्राप्त डेटा की धारा को आसानी से "रिवाइंड" नहीं कर सकते हैं। "6 तत्व पहले" को इंगित करने वाला एक इटरेटर अब सार्थक नहीं है, क्योंकि वह डेटा अब स्मृति में उपलब्ध नहीं हो सकता है। आपके पास स्ट्रीम में केवल वर्तमान स्थिति है।

यह स्पष्ट होना चाहिए कि search को सही ढंग से कार्यान्वित करने के लिए, आपको अनुक्रम के हिस्सों को एक से अधिक बार पार करने में सक्षम होना चाहिए।

+0

यह स्पष्ट प्रतीत होता है ... लेकिन मेरा अनुक्रम खोज अनुक्रम को एक से अधिक बार पार करने के लिए बहुत खुश लगता है .. जब इसे आंशिक मिलान मिलते हैं .. जब पैटर्न मिलान टूट जाता है तो रीसेट हो जाता है ... जब तक कि यह एक पूर्ण मिलान नहीं मिल जाता .. – tuk

+0

फोर एबिट के साथ संघर्ष कर रहा है .... मैंने अपने सेशन में ड्राइवर जोड़ा है जो myfunc को एक पूरा मैच ढूंढता है ..कई आंशिक/अधूरे मैचों के अंत में ... शायद यदि आप एक इनपुट का सुझाव दे सकते हैं जो मेरे func को तोड़ देगा .. मैं – tuk

+2

@tuk को बेहतर ढंग से समझने के लिए चरणबद्ध कर सकता हूं: हाँ, लेकिन आप फ़ंक्शन को यादृच्छिक-एक्सेस इटरेटर्स के साथ कॉल कर रहे हैं (स्ट्रिंग और वेक्टर इटरेटर)। उदाहरण के लिए इसे 'std :: input_iterator' से कॉल करने का प्रयास करें। बेशक, यदि आपका कोड आगे इटरेटर्स पर मिली सुविधाओं पर निर्भर करता है, और आप इसे अग्रेषित इटरेटर से कुछ * मजबूत * कहते हैं, तो यह ठीक काम करेगा। ;) यह देखने के लिए कि क्या यह इनपुट इटरेटर्स के साथ काम करता है, आपको वास्तव में एक इनपुट इटरेटर को अपने फ़ंक्शन में पास करने की आवश्यकता होगी। :) – jalf

संबंधित मुद्दे