2012-11-06 29 views
5

मेरे पास एक ऐसा फ़ंक्शन है जो एक मनमानी-लंबाई स्ट्रिंग से डेटा के 128-बिट ब्लॉक पर चलता है। यदि स्ट्रिंग 128 बिट्स के हिस्सों में समान रूप से विभाजित नहीं है, तो यह तदनुसार गद्देदार होगा।128-बिट भाग में एक स्ट्रिंग पर मैं फिर से कैसे सक्रिय कर सकता हूं?

उद्देश्य फ़ंक्शन में खिलाए गए स्ट्रिंग में डेटा को बदलने का उद्देश्य है।

मैं शुरू में स्ट्रिंग एक ऐसे माध्यम से पाशन के बारे में सोचा:

//This might have stupid errors. Hopefully it stillg gets the point across. 
for (int i = 0; i < strn.size(); i += 16) 
{ 
    string block = strn.substr(i, i + 15); 
    strn.replace(i, i + 15, block); 
} 

मुझे लगता है कि यह काम करेगा, लेकिन मैं सोच रहा हूँ यह करने के लिए एक और अधिक सुरुचिपूर्ण तरीका होना चाहिए। एक विचार जो दिमाग में आया था वह कक्षा में strn को समाहित करना था और अपना खुद का इटरेटर लागू करना था जो 128-बिट भाग में अपनी सामग्री को पढ़ सकता है। यह आकर्षक है क्योंकि कन्स्ट्रक्टर पैडिंग को संभाल सकता है और वर्तमान में उपयोग किए जाने वाले कुछ कार्यों को निजी बनाया जा सकता है, इस प्रकार संभावित दुरुपयोग से परहेज किया जा सकता है। क्या यह एक उपयोगी दृष्टिकोण की तरह लगता है? यदि हां, तो कोई अपने इटरेटर को लागू करने के बारे में कैसे जाता है? विस्तृत स्पष्टीकरण का स्वागत है, क्योंकि मैं सी ++ के साथ बहुत अनुभवहीन हूं।

क्या कोई अन्य, शायद बेहतर, दृष्टिकोण है?

धन्यवाद!

उत्तर

3

कई दृष्टिकोण हैं। अधिक सरल और सीधा वाले लोगों में से एक इस तरह होगा: आप अपना खुद का आकार 128 बिट बना सकते हैं; सरल struct नौकरी करेगा।

typedef struct 
{ 
    char buf[16]; 
} _128bit; 

और इसका इस्तेमाल अपने स्ट्रिंग से अधिक पुनरावृति करने के लिए। इस स्ट्रिंग प्रकार में अपनी स्ट्रिंग की शुरुआत कास्ट करें: _128bit* start = (_128bit*)buffer; और अभिन्न पॉइंटर अंकगणितीय का उपयोग करके इसके साथ पुनरावृत्ति प्रारंभ करें। start पर सभी संचालन इसके आकार के अनुसार संचालित होंगे। जैसे , start++ 128 बिट आगे बढ़ेगा; start-- 128 बिट वापस ले जाएगा। एक बार जब आप वांछित स्थिति में हों, तो इसे वांछित प्रकार पर पुन: दर्ज करें और अपनी कुशलताएं करें।

+0

यह एक साधारण और सुरुचिपूर्ण दृष्टिकोण की तरह लगता है! बस कुछ प्रश्न: 1) क्या '_128 बिट' में अंडरस्कोर का कोई कारण है? 2) टाइपपीफ क्यों? मुझे लगता है कि यह मुझे अन्य चर और स्थिरांक को इसके प्रकार के रूप में डालने की अनुमति देता है ... क्या मेरा अंतर्ज्ञान सही है? 3) यह कैसे है कि '++' ऑपरेटर पहले से ही इस उदाहरण में अधिभारित है? मुझे इसे स्पष्ट रूप से क्यों नहीं करना है? बेहतर सी ++ संरचनाओं की मेरी अज्ञानता के लिए बहुत धन्यवाद और कई माफ़ी! =) – blz

+1

1. यदि मुझे सही ढंग से याद है, तो चर नाम एक अंक से शुरू नहीं हो सकते हैं। 2. हम्म, सी ++ में वास्तव में कोई ज़रूरत नहीं है, सी में यह कोड को छोटा कर सकता है :)। 3. यह पॉइंटर अंकगणित का लाभ है, यह बिंदुओं के संदर्भ में संचालित होता है, अधिक जानकारी के लिए यहां देखें: http://stackoverflow.com/questions/394767/pointer-arithmetic बीटीडब्ल्यू, यह एक शुद्ध सी समाधान है, कोई सी ++ नहीं है – SomeWittyUsername

+0

उपयोग की जाने वाली विशेषताएं ठीक है जो समझ में आता है। हालांकि, मैं अभी भी टाइपपीफ के बारे में थोड़ा अस्पष्ट हूं। क्या 'typedef' कीवर्ड आपको एक नया प्रकार का नाम बनाने की अनुमति नहीं देता है? इस प्रकार, क्या आपके उदाहरण को परिभाषित संरचना के लिए नाम निर्दिष्ट नहीं करना चाहिए? ... 'typedef struct {...}' जैसे कुछ? – blz

1

मैं शायद अनुक्रमण के बजाय iterators के साथ ऐसा होता है, अभी भी पाश के लिए अपने स्वयं के उपयोग करते हुए:

const int NUM_BITS_IN_CHUNK = 128; 
const int CHUNK_SIZE = NUM_BITS_IN_CHUNK/CHAR_BIT; 

for(std::string::const_iterator iter = str.begin(); iter < str.end(); iter += CHUNK_SIZE) 
{ 
    your_func(iter, iter + CHUNK_SIZE); 
} 

बढ़ावा :: iterator_adaptor कोड कुछ इस तरह दिखेगा। ध्यान दें कि उदाहरण में सादगी के लिए मुझे केवल 16 बाइट प्रति चंक मिल रहा है उदाहरण के लिए:

#include <iostream> 
#include <string> 

#include <boost/iterator_adaptors.hpp> 

struct string_chunk_iterator : public boost::iterator_adaptor<string_chunk_iterator, std::string::const_iterator> 
{ 
    string_chunk_iterator(const std::string::const_iterator& base) : iterator_adaptor(base) { } 

private: 
    friend class boost::iterator_core_access; 
    void increment() { this->base_reference() = this->base() + 4; } 
    void advance(typename iterator_adaptor::difference_type n) 
    { 
     this->base_reference() = this->base() + (4 * n); 
    } 
}; 

int main() 
{ 
    const std::string tester(20, 'A'); 

    string_chunk_iterator iter(tester.begin()); 
    string_chunk_iterator str_end(tester.end()); 

    for(; iter != str_end; ++iter) 
    { 
     std::string chunk(&*iter, &*(iter + 1)); 

     std::cout << chunk << std::endl; 
    } 

    return 0; 
} 
+0

क्या 'std :: string :: const_iterator' को उपclass करने का कोई तरीका है, जो इसे '++' के साथ बढ़ा रहा है या 'iter.next()' को कॉल करने से 128 बिट्स बढ़ेगा? इसके अलावा, मैं थोड़ा उलझन में हूँ। मैंने सोचा होगा कि 'iter + = 128' पॉइंटर 128 * बाइट्स * (या इंडेक्स) को स्थानांतरित करेगा। मैं क्या खो रहा हूँ? – blz

+1

@blz मुझे विश्वास है कि आप इस तरह के एक इटरेटर बनाने के लिए 'boost :: iterator_adapter' का उपयोग कर सकते हैं, लेकिन मुझे बढ़ावा देने के उस हिस्से के साथ थोड़ा सा अनुभव नहीं है। आप सही हैं कि 'iter + = 128' वास्तव में 128 बाइट्स से बढ़ेगा। सौभाग्य से, यह नहीं है कि मैं अपने कोड में क्या कर रहा हूं: मैं 16 (बाइट्स) से बढ़ रहा हूं। यही कारण है कि मैंने यह सुनिश्चित करने के लिए स्थिरांक बनाए हैं कि यह अभी भी 16 बिट 'char' वाला सिस्टम कहने पर भी काम करता है। –