2011-12-24 6 views
8

मैं सी ++ प्रारंभिक ऑब्जेक्ट्स 7 वें संस्करण के साथ शुरू करने वाली पुस्तक में प्रोग्रामिंग चुनौतियों में से एक पर काम कर रहा हूं और असाइनमेंट में से एक एसटीएल स्ट्रिंग क्लास से प्राप्त कक्षा बनाने के लिए कहता है। मैं यह समझने के उद्देश्य से प्रश्न पोस्ट कर रहा हूं कि मुझे क्या करने की अनुमति है और मुझे समाधान को कैसे लागू करना है ताकि कोई भी अधिक उन्नत सुझाव प्रदान न कर सके।मैं एसटीएल स्ट्रिंग क्लास में सदस्य चर का उपयोग कैसे करूं?

- के रूप में यह पाठ में लिखा है प्रश्न -

Palindrome परीक्षण

विलोमपद एक स्ट्रिंग है आगे के रूप में ही पिछड़े पढ़ता है। उदाहरण के लिए, शब्द माँ, पिता, मैडम, और रडार पालिंड्रोम हैं। से प्राप्त class Pstring लिखें। Pstring class एक सदस्य समारोह

bool isPalindrome() 

कि निर्धारित करता है कि स्ट्रिंग विलोमपद कहते हैं। एक निर्माता शामिल करें जो STL string ऑब्जेक्ट को पैरामीटर के रूप में लेता है और इसे स्ट्रिंग बेस क्लास कन्स्ट्रक्टर में पास करता है। एक मुख्य प्रोग्राम होने से अपनी कक्षा का परीक्षण करें जो उपयोगकर्ता को स्ट्रिंग में प्रवेश करने के लिए कहता है। प्रोग्राम एक स्ट्रिंग ऑब्जेक्ट को प्रारंभ करने के लिए स्ट्रिंग का उपयोग करता है और फिर यह निर्धारित करने के लिए isPalindrome() को कॉल करता है कि स्ट्रिंग दर्ज एक पालिंड्रोम है या नहीं।

आपको स्ट्रिंग क्लास के सबस्क्रिप्ट ऑपरेटर [] का उपयोग करना उपयोगी हो सकता है: यदि str एक स्ट्रिंग ऑब्जेक्ट है और के एक पूर्णांक है, तो str [k] स्ट्रिंग में स्थिति k पर कैरेक्टर देता है।

- अंत -

मेरा मुख्य सवाल है कि कैसे मैं सदस्य चर जो मेरे स्ट्रिंग वस्तु धारण का उपयोग करते हैं, तो वर्ग मैं से Pstring पाने रहा एक वर्ग मैं नहीं लिखा था और मैं पता नहीं कैसे यह अपने सदस्यों को लागू करता है?

उदाहरण के लिए,

#include <string> 
using namespace std; 

class Pstring : public string 
{ 
public: 
    Pstring(std::string text) 
    : string(text) { } 

    bool isPalindrome() 
    { 
    // How do I access the string if I am passing it to the base class? 

    // What I think I should do is... 
    bool is_palindrome = true; 
    auto iBegin = begin(); 
    auto iEnd = end() - 1; 

    while (iBegin < iEnd && is_palindrome) 
    { 
     if (*iBegin++ != *iEnd--) 
     is_palindrome = false; 
    } 

    return is_palindrome; 

    // But I think this is wrong because... 
    // #1 The book did not discuss the keyword auto yet 
    // #2 The book discussed when a class is derived from another class, 
    // how the members from super class will be accessible to the sub class. 
    // However, with this assignment, I don't see how to access the members. 
    } 
} 

कारण लग रहा है मैं जैसे मैं कर रहा हूँ इस गलत तरीके से क्योंकि काम सबस्क्रिप्ट अंकन का उपयोग का उल्लेख है, तथापि, मुझे समझ नहीं आता कैसे सबस्क्रिप्ट संकेतन का उपयोग करने के लिए अगर मैं डॉन ' वेरिएबल का नाम पता है जहां स्ट्रिंग संग्रहित है।

किसी भी मदद की बहुत सराहना की जाएगी क्योंकि लेखक समाधान प्रदान नहीं करता है जब तक कि मैं एक प्रशिक्षक नहीं हूं जो मेरी राय में काफी लंगड़ा है। इसे शायद इस तथ्य से करना है कि यह एक अकादमिक पाठ है।

+6

कभी STL वर्गों से निकाले जाते हैं। हमेशा एक बुरा विचार। आप इसके बजाय संरचना का प्रयास क्यों नहीं करते? – Lalaland

+5

लेखक समाधान प्रदान नहीं कर सकता क्योंकि वह मूर्ख है। – Duck

+0

@ ईथन स्टीनबर्ग मैं पूरी तरह से सहमत हूं, हालांकि, यह असाइनमेंट विशेष रूप से ऐसा करने के लिए कहता है। –

उत्तर

3

आपको std :: स्ट्रिंग से प्राप्त नहीं होना चाहिए, क्योंकि इसे इसके लिए डिज़ाइन नहीं किया गया था, न ही आपको पैलिंड्रोम खोजने के लिए आवश्यकता है। Inheriting and overriding functions of a std::string?

Palindrome समाधान (इस सवाल से: Check if a string is palindrome इस से लिंक किया गया: C++ Palindrome finder optimization)

#include <algorithm> 

bool isPal(const string& testing) { 
    return std::equal(testing.begin(), testing.begin() + testing.size()/2, testing.rbegin()); 
} 

उस किताब की गुणवत्ता संदिग्ध लगता है

इस देखें। नि: शुल्क कार्य (जो आप पूछते हैं उसके आधार पर) लगभग हमेशा सदस्य कार्यों पर पसंद करते हैं, और विशेष रूप से विरासत से अधिक पसंद करते हैं।


आप विरासत उपयोग करना आवश्यक है:

class Pstring : public string 
{ 
    //... 

    bool isPalindrome() 
    { 
     return std::equal(begin(), begin() + size()/2, rbegin()); 

     // as a side-note, 'iterator' will refer to the inherited return type of begin() 
     // Also, 'operator[](x)' will call the subscript operator 
    } 
}; 
+0

प्रतिक्रिया के लिए धन्यवाद। मुझे पता है कि यह अच्छा अभ्यास नहीं है। हालांकि, असाइनमेंट विशेष रूप से मुझे अपने समाधान को लागू करने के लिए कहता है जिस तरह से मैं ऊपर की कोशिश कर रहा हूं। एक वर्ग बनाकर जो एसटीएल स्ट्रिंग क्लास से लिया गया है और फिर स्ट्रिंग एक पालिंड्रोम है, तो परीक्षण के लिए एक फ़ंक्शन बनाने के लिए। मैं असाइनमेंट पूरा करने की कोशिश कर रहा हूं। मैं किसी भी और उन्नत तरीकों का उपयोग नहीं कर सकता या अपना खुद का समाधान लागू नहीं कर सकता जो कि असाइनमेंट से अनुरोध करता है कि इससे कैसे विचलन होता है। –

+0

@ fhaddad78 आप उस कोड को सदस्य फ़ंक्शन में बस लपेट सकते हैं। std :: स्ट्रिंग के सदस्य फ़ंक्शन अभी भी उपलब्ध हैं। – Pubby

+0

प्रतिक्रिया के लिए धन्यवाद। मैंने कॉलिंग ऑपरेटर [] (x) को सीधे अनदेखा कर दिया और इन्फिक्स नोटेशन का उपयोग करने का तरीका जानने का प्रयास कर रहा था। –

0

आप ऑटो का उपयोग नहीं करना चाहते हैं, तो आप बस std::string::iterator बजाय उपयोग कर सकते हैं, जो है क्या auto इस मामले में करने के लिए वैसे भी हल करने है।

इस प्रकार समस्या # 1 संतुष्ट है।


जब आप begin() बुला रहे हैं और end() आप सदस्यों begin() और end() सुपर क्लास std :: स्ट्रिंग में बुला रहे हैं।

इस प्रकार समस्या # 2 संतुष्ट है।

1

पुस्तक में auto शामिल नहीं था क्योंकि वह कीवर्ड हाल ही में भाषा में जोड़ा गया था। यदि आपका कंपाइलर एक वर्ष से अधिक पुराना है या बड़े नामों में से एक नहीं है तो शायद यह इसका समर्थन नहीं करता है।

इस समस्या के लिए आपको उचित समाधान के लिए किसी भी सदस्य चर का उपयोग करने की आवश्यकता नहीं है, इसलिए चिंता करने की कोई आवश्यकता नहीं है कि वे क्या हैं या वे पहुंच योग्य हैं या नहीं। अच्छी बात यह है कि, इनमें से कोई भी मानक द्वारा निर्दिष्ट नहीं है - यह आपके विशेष कंपाइलर द्वारा परिभाषित सभी कार्यान्वयन विवरण है, और यदि आप खुद को गहराई से खोदते हैं तो आपको खुद से पूछना चाहिए कि आप क्या गलत कर रहे हैं।

निश्चित रूप से मूल वर्ग के सदस्य कार्यों को बाल वर्ग के सदस्य कार्यों के रूप में उपयोग किया जाता है - आप उन्हें बस कॉल करते हैं।

सदस्य ऑपरेटर ओवरलोड कुछ छोटी सी चीजें हैं, लेकिन अभी भी बहुत खराब नहीं हैं। आपको उन्हें उदाहरण देने के लिए उदाहरण की आपूर्ति करने की आवश्यकता है, जो *this है। आप उन्हें operator कीवर्ड के साथ भी कॉल कर सकते हैं लेकिन मेरी राय में यह थोड़ा गड़बड़ है।

if ((*this)[i] == (*this)[j]) 

if (operator[](i) == operator[](j)) 
+1

'ऑटो' कीवर्ड बी के बाद से कुछ उपयोगी रहा है, ऑटो कुछ उपयोगी है जो हाल ही में जोड़ा गया था। – Pubby

+0

@ मार्क रान्ससम ओके। मैं इसे एक साथ एक बुरे असाइनमेंट के लिए चॉकलेट कर रहा हूं। मैं इस समस्या से वास्तव में उलझन में था क्योंकि यह मेरे समाधान में सबस्क्रिप्ट नोटेशन का उपयोग करने का उल्लेख करता है, जिसे मैं समझ नहीं पा रहा हूं कि जब तक मैं सबस्क्रिप्ट ऑपरेटर को अधिभारित नहीं करता था या जब तक कि मेरी स्ट्रिंग सदस्य चर में बैठी न हो, जिसे मैं ढूंढ सकता था, लेकिन ऐसा लगता है जैसे मैं नहीं कर सकता। –

+1

@ fhaddad78, मैंने सदस्य ऑपरेटरों को शामिल करने के लिए उत्तर अपडेट किया है। –

0

इस प्रयास करें:

#include <string> 

class Pstring : public std::string 
{ 
public: 
    Pstring(const std::string &text) 
     : std::string(text) { } 

    bool isPalindrome() 
    { 
     std::string::size_type len = length(); 
     std::string::size_type half = len/2; 
     for (std::string::size_type idx = 0; idx < half; ++idx) 
     { 
      if ((*this)[idx] != (*this)[len-idx-1]) 
       return false; 
     } 
     return true; 
    } 
}; 
संबंधित मुद्दे