2013-03-19 11 views
6

मैं पुनरावर्ती रूप से एक फ़ंक्शन को एक सबस्ट्रिंग के रूप में गुजरने वाला फ़ंक्शन कहता हूं जो हमेशा मौजूदा स्ट्रिंग की शुरुआत से स्थिति तक शुरू होता है। अगर मैं सी का उपयोग कर रहा था, तो मैं पॉइंटर को स्ट्रिंग की पहली स्थिति और फिर आवश्यक लंबाई तक पास कर सकता था। फिर भी, मैं कक्षा string कक्षा का उपयोग कर एक ही परिणाम प्राप्त करना चाहता हूं। क्या यह संभव है? अगर मैं const का उपयोग करता हूं, तो क्या संकलक स्वयं को अनुकूलन बनाने के लिए पर्याप्त स्मार्ट है? इससे भी बेहतर, क्या स्वयं को जांचने का कोई तरीका है कि संकलक वास्तव में तर्क की एक प्रति बनाता है या संदर्भ पास करता है?मैं संदर्भ द्वारा एक सबस्ट्रिंग कैसे पास कर सकता हूं?

मेरा प्रश्न निम्नलिखित कोड लिखने के बाद प्रेरित किया गया था जो Alphacode पर पीजी पर समस्या को पार करता है, जब कोई atof के बजाय atoi का उपयोग करता है।

#include <iostream> 
#include <algorithm> 
#include <map> 
#include <vector> 
#include <string> 

using namespace std; 

map<string, int> cache; 

bool valid_character_number(string a) { 
    return 0 < stoi(a.substr(a.size() - 2, 2)) && stoi(a.substr(a.size() - 2, 2)) <= 26; 
} 

bool zero_last_digit(string a) { 
    return a[a.size() - 1] == '0'; 
} 
bool zero_before_last_digit(string a) { 
    return a[a.size() - 2] == '0'; 
} 

int decodings(string a) { 
    if (a.size() == 0) 
     return 1; 
    if (a.size() == 1) { 
     if (zero_last_digit(a)) 
      return 0; 
     else 
      return 1; 
    } 
    if (cache.find(a) != cache.end()) 
     return cache[a]; 

    if (zero_last_digit(a) && valid_character_number(a)) 
     return cache[a] = decodings(a.substr(0, a.size() - 2)); 
    else if (valid_character_number(a) && !zero_before_last_digit(a)) 
     return cache[a] = decodings(a.substr(0, a.size() - 1)) + decodings(a.substr(0, a.size() - 2)); 
    else 
     return cache[a] = decodings(a.substr(0, a.size() - 1)); 
} 

int main() { 
    string input; 
    while (true) { 
     cin >> input; 
     if (input.size() == 1 && stoi(input) == 0) 
      return 0; 
     cout << decodings(input) << endl; 
    } 

    return 0; 
} 
+0

मैं कहीं भी जहां नहीं देख सकते हैं आपके फ़ंक्शन पैरामीटर को संशोधित करते हैं। 'Const std :: string &' का प्रयोग करें। – chris

+1

देखें ['boost :: string_ref'] (http://www.boost.org/libs/utility/doc/html/string_ref.html)। – ildjarn

उत्तर

6

आप इस उद्देश्य के लिए std::string उपयोग नहीं कर सकते, लेकिन आप आसानी से अपने खुद के एक वर्ग है कि iterators की एक जोड़ी (शुरू और समाप्त) एक और स्ट्रिंग में, या एक सी शैली चार * और आकार धारण कर सकते हैं। सी ++ 11 के साथ (जब से आप इसे टैग करते हैं), आपको अपने नए प्रकार के तार बनाने के लिए उपयोगकर्ता परिभाषित शाब्दिक वाक्यविन्यास भी बनाने में सक्षम होना चाहिए।

2

आप इस तरह अपने खुद के आवरण वर्ग का उपयोग कर सकते हैं:

struct RefString 
{ 
    RefString(const std::string & s, int i, int l) : s(s), i(i), l(l) {} 

    const char & operator [] (int x) const { 
     return s[i+x]; 
    } 

    size_t length() const { 
     return l; 
    } 

    bool operator < (const RefString & s2) const { 
     return s.compare(i, l, s2.s, s2.i, s2.l) < 0; 
    } 

private: 
    const std::string & s; 
    int i; 
    int l; 
}; 

std::ostream & operator << (std::ostream &stream, const RefString & ms) { 
    for (int i = 0; i < ms.length(); i++) 
     stream << ms[i]; 
    return stream; 
} 

और अद्वितीय सबस्ट्रिंग set बनाने के लिए इस तरह इसका इस्तेमाल, उदाहरण के लिए:

std::string s = "hello"; 
std::set<RefString> st; 
for (int i = 0; i < s.length(); i++) 
for (int j = i; j < s.length(); j++) 
    st.insert(RefString(s, i, j-i+1)); 
+0

सूचकांक ऑपरेटर एक कॉन्स्ट संदर्भ क्यों लौटा रहा है? और स्ट्रिंग संदर्भ सदस्य बिल्कुल क्यों है? – renonsz

+0

प्रदान किए गए समाधान @renonsz किसी स्ट्रिंग प्रतिलिपि के बिना सबस्ट्रिंग उदाहरणों की अनुमति देता है। इसलिए संभावित भाई RefStrings को गैर-संशोधित रखने के लिए रेफस्टिंग को संशोधित करने की अनुमति नहीं है। – k06a

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