C: What is the best and fastest way to concatenate strings -


मैं वर्तमान में strcat () फ़ंक्शन से string.h का उपयोग करके तार में तार जोड़ता हूं लाइब्रेरी।

मैंने इसके बारे में सोचा, और मुझे यह निष्कर्ष मिला कि यह बहुत महँगा समारोह होना चाहिए, जैसा कि पहले जोड़ना शुरू होता है, इसे चार सरणी पर फिर से चलना पड़ता है उदाहरण के लिए, यदि मैं स्ट्रिंग "घोड़ों" को जोड़ता है 1000 बार strcat () का उपयोग करते हुए '<0> कोड>, मुझे (1 + 2 + 3 + ... + 1000) * स्ट्रेलन ("घोड़ों") का भुगतान करना होगा = (1000 * 1001) / 2 * 6 = 3003000

मैंने स्ट्रिंग की लंबाई के साथ एक पूर्णांक बनाए रखने के गैर-मानक तरीके के बारे में सोचा और फिर strcat () को स्ट्रिंग के अंत में सूचक को भेजना:

  घूर्णन (dest + dest_len, "string");  

इस मामले में, मैं केवल 1000 * strlen ("horses") = 1000 * 6 = 6000 का भुगतान करूंगा।

6000 3003000 की तुलना में बहुत कम है, इसलिए यदि आप इस तरह के कंसैक्शन के बहुत सारे हैं, तो यह प्रदर्शन के लिए बहुत महत्वपूर्ण हो सकता है।

क्या यह करने के लिए कुछ और मानक तरीका है, मेरे समाधान से बेहतर दिखता है?

जोएल स्पोलस्की, अपने लेख में, strcat के साथ अक्षम स्ट्रिंग समापन की समस्या का वर्णन करता है Shlemiel चित्रकार का एल्गोरिथ्म (लेख पढ़ा, यह काफी अच्छा है)। अक्षम कोड का एक उदाहरण के रूप में, वह यह उदाहरण देता है, जो ओ (n 2 ) समय में चलता है:

  char bigstring [1000]; / * मुझे कभी नहीं पता है कि कितना आवंटित करना है ... * / bigstring [0] = '\ 0'; घुमटा (बड़ी स्ट्रिंग, "जॉन,"); घुमटा (बड़ा स्ट्रिंग, "पॉल,"); घुमटा (बड़ी स्ट्रिंग, "जॉर्ज,"); घुमटा (बड़ा स्ट्रिंग, "जोएल");  

पहली स्ट्रिंग पहली बार पर चलने में कोई समस्या नहीं है; चूंकि हमें पहले से दूसरी स्ट्रिंग पर चलना पड़ता है, एक strcat के परिणाम समय की लंबाई में रैखिक है। मल्टीपल घुमंतू s हालांकि समस्याग्रस्त है, क्योंकि हम पहले से संक्रमित परिणामों पर बार-बार चलते हैं वह यह विकल्प प्रदान करता है:

हम इसे कैसे ठीक करते हैं? कुछ स्मार्ट सी प्रोग्रामर ने अपना स्वयं का mystrcat लागू किया है:

  char * mystrcat (char * dest, char * src) {जबकि (* dest) dest ++; जबकि (* dest ++ = * src ++); वापसी - डेस्ट; }  

हमने यहाँ क्या किया है? बहुत कम अतिरिक्त लागत पर हम नए, लंबी स्ट्रिंग के अंत में एक संकेतक लौट रहे हैं। इस तरह से कोड जो इस फ़ंक्शन को कॉल करता है वह स्ट्रिंग को पुन: स्कैन किए बिना आगे जोड़ना तय कर सकता है:

  char bigstring [1000]; / * मुझे कभी नहीं पता है कि कितना आवंटित करना है ... * / char * p = bigString; बड़ी स्ट्रिंग [0] = '\ 0'; P = mystrcat (पी, "जॉन,"); P = mystrcat (पी, "पॉल,"); P = mystrcat (पी, "जॉर्ज,"); P = mystrcat (पी, "जोएल");  

यह निश्चित रूप से, निष्पादन में रैखिक है, एन-स्क्वेर्ड नहीं है, इसलिए इसे गिरावट से ग्रस्त नहीं होता है, जब आपके पास बहुत सारे सामान मिलते हैं।

बेशक, आप मानक सी स्ट्रिंग्स का उपयोग करना चाहते हैं, तो आप ऐसा कर सकते हैं। वैकल्पिक आप स्ट्रिंग की लंबाई को कैशिंग और एक विशेष संयोजन समारोह (जैसे, कॉलिंग strcat को थोड़ा अलग तर्कों के साथ) का उपयोग करने का वर्णन कर रहे हैं पास्कल स्ट्रिंग्स पर एक भिन्नता है, जो जोएल ने भी उल्लेख किया है :

पास्कल के डिजाइनर इस समस्या से परिचित थे और स्ट्रिंग के पहले बाइट में एक बाइट गिनती को संचित करके "फिक्स्ड" थे। इन्हें पास्कल स्ट्रिंग कहा जाता है वे शून्य हो सकते हैं और शून्य समाप्त नहीं किए जा सकते हैं। चूंकि एक बाइट केवल 0 से 255 के बीच की संख्या को संग्रहीत कर सकता है, पास्कल स्ट्रिंग्स लंबाई में 255 बाइट तक सीमित हैं, लेकिन क्योंकि वे निरस्त नहीं हैं इसलिए वे एएससीआईजेड स्ट्रिंग्स के समान मेमोरी स्मृति पर कब्जा करते हैं। पास्कल स्ट्रिंग्स के बारे में महान बात यह है कि आपके स्ट्रिंग की लंबाई का पता लगाने के लिए आपको कभी भी एक पाश नहीं है। पास्कल में एक स्ट्रिंग की लंबाई ढूंढना एक संपूर्ण लूप के बजाय एक विधानसभा निर्देश है। यह स्मारकीय रूप से तेज है।

...

एक लंबे समय के लिए, यदि आप अपने सी कोड में पास्कल स्ट्रिंग को शाब्दिक रखना चाहते हैं, तो आपको लिखना होगा:

  चार * str = "\ 006 हेलो!";  

हां, आपको बाइट्स को हाथ से गिनना पड़ा, अपने आप को, और हार्डकोड को अपने स्ट्रिंग के पहले बाइट में। आलसी प्रोग्रामर ऐसा करेंगे, और धीमे कार्यक्रम होंगे:

  char * str = "* नमस्कार!"; Str [0] = स्ट्रेलन (str) - 1;  

Comments