void TrimRight( char *s ) फ़ंक्शन है, जिसमें तर्क के रूप में एक बहुत लंबी एस-शैली स्ट्रिंग है। एक पारित स्ट्रिंग में अंतिम शब्द के बाद और इसकी पूरी लंबाई के बाद बहुत सारे सफेद स्थान होते हैं। यह आवश्यक है कि फ़ंक्शन दाईं ओर अतिरिक्त सफेद रिक्त स्थान को ट्रिम करना है।

मैंने इस तरह दिखने वाले कार्यान्वयन का सुझाव दिया:

void TrimRight(char *str) {
    char *space_pos{};  // last space position
    auto iterator{str}; // string iterator
    while (*iterator != '\0') {
      if (*iterator == ' ') { // save first space
        if (!space_pos) {
          space_pos = iterator;
        }
      } else {
        space_pos = nullptr;
      }
      ++iterator;
    }
    if (space_pos) { // if the string does not end with alpha
      *space_pos = '\0';
    }   
}

यह बहुत अच्छी तरह से काम करता है लेकिन N मेमोरी एक्सेस अधिक लगता है, क्योंकि मुझे दिया गया कार्य बताता है कि एक स्ट्रिंग बहुत लंबी है और इसमें कई सफेद स्थान हैं। इसलिए, सवाल उठाया गया है: क्या कई मेमोरी एक्सेस को कम करने के लिए फ़ंक्शन को परिष्कृत करने का कोई तरीका है?

c++
2
Denis319199 2 सितंबर 2021, 23:12

2 जवाब

सबसे बढ़िया उत्तर

आप कभी नहीं जानते कि आपको गैर-स्पेस कैरेक्टर कहां मिल सकता है, इसलिए आपको पूरी स्ट्रिंग को देखना होगा।

हालांकि आप इसे बहुत कम तुलनाओं के साथ कर सकते हैं।

उदाहरण:

void TrimRight(char *iterator) {
    for(;;) {
        // Loop for as long as the string has not ended and non-space chars are
        // found.
        for(;*iterator != ' '; ++iterator) {
            // Return if the end of the string is found. If the end of the string
            // is found here, it did not end with spaces.
            if(*iterator == '\0') return;
        }

        // A space position is found, store it.
        char* space_pos = iterator;

        // Loop for as long as there are spaces.
        do ++iterator; while(*iterator == ' ');

        // Break out if the end of the string is found. If the end of the string
        // is found at this stage, it ended with spaces so trim the string.
        if(*iterator == '\0') {
            *space_pos = '\0';
            break;
        }
    }
}

नोट: आप अपने टेक्स्ट में व्हाइटस्पेस का उल्लेख करते हैं लेकिन आप केवल रिक्त स्थान के लिए परीक्षण करते हैं। अगर आपको वास्तव में सभी पिछली व्हाइटस्पेस को ट्रिम करना है, तो ऊपर दिए गए ' ' के साथ तुलना को std::isspace() परीक्षण, इस तरह:

while(*iterator != '\0' && 
      !std::isspace(static_cast<unsigned char>(*iterator))) ++iterator;

तथा

do ++iterator; while(static_cast<unsigned char>(std::isspace(*iterator)));
2
Ted Lyngmo 4 सितंबर 2021, 09:30

मुझे नहीं लगता कि आप पूरी स्ट्रिंग पर पुनरावृत्ति से बच सकते हैं, लेकिन आप उस कोड को सरल बना सकते हैं जो इसे करता है:

#include <string.h>

void TrimRight(char * str) {
   char * iterator = strchr(str, '\0');  // get NUL terminator byte
   while(--iterator >= str)
   {
      if (*iterator == ' ') *iterator = '\0';
                       else break;
   }
}

यद्यपि जैसा कि 0x5453 ने ऊपर उनकी टिप्पणी में उल्लेख किया है, यदि आप पहले से ही स्ट्रिंग की लंबाई जानते हैं और इसे एक तर्क के रूप में पारित कर सकते हैं, तो आप strchr() पर कॉल से बचने के लिए उस तथ्य का लाभ उठा सकते हैं और इस तरह पुनरावृत्ति से बच सकते हैं। स्ट्रिंग के ऊपर:

void FasterTrimRight(char * str, size_t strlenStr) {
   char * iterator = str+strlenStr;  // get NUL terminator byte
   while(--iterator >= str)
   {
      if (*iterator == ' ') *iterator = '\0';
                       else break;
   }
}
0
Jeremy Friesner 2 सितंबर 2021, 21:06