2011-08-31 18 views
8

में एक स्ट्रिंग में शब्द क्रम पीछे मैं, जैसे जगह में एक वाक्य में शब्दों का क्रम उल्टा करने के लिए कोशिश कर रहा हूँ:जगह

यह वाक्य शब्द उलट कर रहे हैं।

उलट हो जाता है। शब्द वाक्य यह

यह मैं अब तक जो लगभग काम करता है क्या है, है: मैं strrev फ़ंक्शन का उपयोग स्ट्रिंग उल्टा करने के लिए, और फिर inprev समारोह व्यक्तिगत रूप से strrev कार्य करने के लिए प्रत्येक शब्द को भेजने के लिए, उल्टा करने के लिए उन्हें मूल अभिविन्यास पर वापस, लेकिन उलट क्रम में। स्ट्रैव फ़ंक्शन की शुरुआत और अंत के लिए पॉइंटर भेजना थोड़ा मूर्खतापूर्ण प्रतीत हो सकता है, लेकिन यह उसी फ़ंक्शन को inprev() में उपयोग करने की अनुमति देता है, जो व्यक्तिगत शब्दों की शुरुआत और अंत में सूचक को भेजता है।

Foobar अपने दोस्तों, foobar

raboof, sdneirf ym rabooF

foobarfriends, मेरे Foobar

समस्या यह है कि यह है:

#include <stdio.h> 
#include <string.h> 

void strrev(char * start, char * end); 
void inprev(char * start); 

int main(void) 
{ 
    char str[] = "Foobar my friends, foobar"; 
    char * end = (str + strlen(str) -1); 
    puts(str); 
    strrev(str, end); 
    puts(str); 
    inprev(str); 

    puts(str); 

    return 0; 
} 

void strrev(char * start, char * end) 
{ 
    char temp; 

while (end > start) 
    { 
    temp = *start; 
    *start = *end; 
    *end = temp; 
     start++; 
     end--; 
    } 
} 

void inprev(char * start) 
{ 
    char * first = start; 
    char * spcpnt = start; 
    while (*spcpnt) 
    { 
     while (*spcpnt != ' ' && *spcpnt) 
      spcpnt++; 
     strrev(start, spcpnt-1);   // removing the -1 sends the space on the 
     start = spcpnt++;    // other side to be reversed, doesn't stop 
             // the problem. 

    } 

} 

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

+1

एक्स स्पेस का सामना करते समय आपको क्या करना चाहिए? क्या वे पहले या बाद में शब्द से संबंधित हैं? – RedX

+0

+1 अच्छी समस्या :)। यदि मेरे पास थोड़ा समय होगा तो मैं समाधान प्रदान करूंगा –

+0

मुझे लगता है कि आप पहले अक्षर को एक बड़ा नहीं बनाना चाहते हैं, क्योंकि आपका उदाहरण दिखाता है ... – imacake

उत्तर

5

शब्दों के बीच स्थान को छोड़ने के लिए आपको inprev फ़ंक्शन में start फ़ंक्शन को स्थानांतरित करने की आवश्यकता है। जैसा कि यह गृहकार्य प्रतीत होता है (अगर मैं गलत हूं तो मुझे सही करें) मैं बस इतना कहूंगा कि आपको केवल एक ऑपरेटर के स्थान को स्थानांतरित करना है।

लेकिन, यह एक समस्या उत्पन्न करता है, अर्थात्, inprev एक बफर ओवररन करता है क्योंकि खोज ठीक से समाप्त नहीं होती है। ऐसा करने का एक बेहतर तरीका यह है:

while not end of string 
    search for start of word 
    start = start of word 
    search for end of word 
    strrev (start, end) 

और यह भी कई रिक्त स्थान का ख्याल रखेगा। इसके अलावा, यू +0020 (एएससीआईआईआई 32, एक स्पेस) एकमात्र सफेद अंतरिक्ष चरित्र नहीं है। मानक लाइब्रेरी फ़ंक्शन हैं जो वर्णों का परीक्षण करते हैं। वे <ctype.h> में हैं और is... से शुरू करें, उदा। isspace

+0

धन्यवाद! मेरे निश्चित एल्गोरिदम के साथ मूल प्रश्न अपडेट किया गया। होमवर्क बीटीडब्ल्यू नहीं, इसे नौकरी साक्षात्कार के प्रश्न में प्रस्तुत किया और सोचा कि मुझे मज़ा के लिए एक दरार होगी। – Matt

+1

@Matt कृपया प्रश्न में मूल कोड को ठीक न करें! इससे भविष्य में इसे पढ़ने वाले किसी भी व्यक्ति के लिए सवाल बेकार हो जाता है। मैं उस संपादन को रोलबैक करूंगा। – razlebe

+1

@ मैट: razlebe की टिप्पणी में जोड़ने के लिए, आप प्रश्न को संपादित करने के बजाय अद्यतन कोड को उत्तर के रूप में पोस्ट कर सकते हैं। – Skizz

0

एक समाधान का पता चला; यहां मेरा संशोधित कार्य है जो ठीक से काम करता है। के रूप में आप सिर्फ str -1 strrev कार्य करने के लिए पारित कर सकते हैं

void inprev(char * str) 
{ 
    _Bool inword = 0; 
    char * wordend; 
    char * wordstart; 

    while(*str) 
    { 
     if(!isspace(*str) && (inword == 0)) 
     { 
      wordstart = str; 
      inword = 1; 
     } 
     else if (isspace(*str) && (inword == 1)) 
     { 
      wordend = str-1; 
      inword = 0; 
      strrev(wordstart, wordend); 
     } 

     str++; 
    } 

    if (*str == '\0') 
     strrev(wordstart, str-1); 

} 

चार * wordend uneccessary है, लेकिन यह यह थोड़ा और अधिक स्पष्ट क्या हो रहा है बनाता है।

1

कभी-कभी चीजें आसान होती हैं यदि आप पॉइंटर्स का उपयोग नहीं करते हैं लेकिन ऑफसेट्स का उपयोग नहीं करते हैं। strspn() और strcspn() लाइब्रेरी आपको ऑफसेट्स, का उपयोग करने के लिए अधिक या कम बल देती है और अंत में स्ट्रिंग स्थिति को अच्छी तरह से सौदा करती है।

#include <stdio.h> 
#include <string.h> 

size_t revword(char *str); 
void revmem(void *ptr, size_t len); 

size_t revword(char *str) { 
size_t pos,len; 

for (pos=len=0; str[pos]; pos += len) { 
     len = strspn(str+pos, " \t\n\r"); 
     if (len) continue; 
     len = strcspn(str+pos, " \t\n\r"); 
     if (!len) continue; 
     revmem(str+pos, len); 
     } 
revmem(str, pos); 
return len; 
} 

void revmem(void *ptr, size_t len) 
{ 
size_t idx; 
char *str = (char*) ptr; 

if (len-- < 2) return; 

for (idx = 0; idx < len; idx++,len--) { 
     char tmp = str[idx]; 
     str[idx] = str[len]; 
     str[len] = tmp; 
     } 
} 

int main (int argc, char **argv) 
{ 

if (!argv[1]) return 0; 
revword(argv[1]); 
printf("'%s'\n", argv[1]); 

return 0; 
}                       
+0

क्या आप यह बताते हुए कुछ टिप्पणियां जोड़ पाएंगे कि क्या हो रहा है? इसका पालन करना थोड़ा मुश्किल है, उदाहरण के लिए, संशोधित फ़ंक्शन में क्या हो रहा है। – Matt

+0

ठीक है: लूप में, मैं लगातार सफेद जगह (strspn() कॉल) की लंबाई मापता हूं, और इसे छोड़ देता हूं। इसके बाद मैं लगातार * गैर * सफेद जगह (strcspn() कॉल) की लंबाई मापता हूं और इसे उलट देता हूं। लूप के अंत में मेरे पास स्ट्रिंग की पूरी लंबाई जमा होती है और पूरी स्ट्रिंग को उलट देती है। – wildplasser

+0

कूल, चीयर्स मैन! – Matt

0

निम्नलिखित एल्गोरिदम जगह में है और 2 चरणों में चलता है। सबसे पहले यह पूरी स्ट्रिंग को उलट देता है। फिर यह प्रत्येक शब्द को उलट देता है।

#include <stdio.h> 

void reverse(char *str, int len) 
{ 
    char *p = str; 
    char *e = str + len - 1; 

    while (p != e) { 
     *p ^= *e ^= *p ^= *e; 
     p++; 
     e--; 
    } 
} 

void reverse_words(char *str) 
{ 
    char *p; 

    // First, reverse the entire string 
    reverse(str, strlen(str)); 

    // Then, reverse each word 
    p = str; 
    while (*p) { 
     char *e = p; 
     while (*e != ' ' && *e != '\0') { 
      e++; 
     } 

     reverse(p, e - p); 
     printf("%.*s%c", e - p, p, *e); 

     if (*e == '\0') 
      break; 
     else 
      p = e + 1; 
    } 
} 

int main(void) { 
    char buf[] = "Bob likes Alice"; 
    reverse_words(buf); 
    return 0; 
} 
+0

यदि 'लेन' भी है, तो फ़ंक्शन 'रिवर्स' सेगफॉल्ट का कारण बन जाएगा। कोशिश करें जबकि जबकि (पी <ई) '। –

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