Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di Iena87
    Registrato dal
    Dec 2003
    Messaggi
    429

    [C++] Ribaltamento stringa con ricorsione

    Mi direste un metodo per ribaltare una stringa utilizzando una procedura ricorsiva?

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Crei una funzione che prende in input una stringa e restituisce in output l'ultimo carattere della stringa, concatenato al risultato della stessa funzione, a cui viene passata tutta la prima stringa tranne l'ultimo carattere.
    Ecco un esempio:
    codice:
    char *ribalta(char *s) {
       char *tmp;
       char *s2;
       tmp = (char *) malloc(strlen(s) * sizeof(char));
       s2 = (char *) malloc(strlen(s) * sizeof(char));
       strcpy(s2, s);
       if (!strlen(s)) {
          strcat(tmp, "");
       } else {
          tmp[0] = s2[strlen(s2)-1];
          s2[strlen(s2)-1] = '\0';
          strcat(tmp, ribalta(s2));
       }
       
       return tmp;
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it L'avatar di Iena87
    Registrato dal
    Dec 2003
    Messaggi
    429
    Originariamente inviato da LeleFT
    Crei una funzione che prende in input una stringa e restituisce in output l'ultimo carattere della stringa, concatenato al risultato della stessa funzione, a cui viene passata tutta la prima stringa tranne l'ultimo carattere.
    Ecco un esempio:
    codice:
    char *ribalta(char *s) {
       char *tmp;
       char *s2;
       tmp = (char *) malloc(strlen(s) * sizeof(char));
       s2 = (char *) malloc(strlen(s) * sizeof(char));
       strcpy(s2, s);
       if (!strlen(s)) {
          strcat(tmp, "");
       } else {
          tmp[0] = s2[strlen(s2)-1];
          s2[strlen(s2)-1] = '\0';
          strcat(tmp, ribalta(s2));
       }
       
       return tmp;
    }
    Ciao.
    Ti ringrazio, ma a trascriverlo in maniera assai + semplice?
    Sto ancora ad un basso livello di programmazione...malloc e funzioni riguardanti le stringhe ancore nn li conosco...

  4. #4
    una soluzione potrebbe essere questa

    codice:
    void ribalta(char* s, int i, int j)
    {
      if (i < j)
      {
        /* scambia s[i] <-> s[j] */
        t = s[i]
        s[i] = s[j];
        s[j] = t;
        ribalta(s, i+1, j-1);
      }   
    }
    la chiamata
    codice:
    ribalta(s, 0, strlen(s)-1);

  5. #5
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    L'esempio che ti e stato fatto da LeleFT contiene qualche errore, ad esempio alloca un array piu corto di uno di quanto dovrebbe essere, questa è una versione corretta:

    codice:
    1  char *ribalta2(char *s){
    2	int len = strlen(s);
    3	char * rib_s = (char *)malloc((len + 1) * sizeof(char));
    4	rib_s[len] = '\0';
    5	if(len == 0)
    6		return rib_s;
    7	rib_s[0] = s[len - 1];
    8	char *tmp = (char *)malloc((len + 1) * sizeof(char));
    9	strcpy(tmp, s);
    10	tmp[len - 1] = '\0';
    11	strcpy(rib_s + 1, ribalta2(tmp));
    12	free(tmp);
    13	return rib_s;
    14 }
    quello che fa la funzione è allocare un nuovo array di caratteri rib_s che dovrà contenere la stringa ribaltata (3); quindi l'ultimo carattere della stringa originaria è copiato nella prima posizione della stringa ribaltata (7). La funzione deve poi essere richiamata ricorsivamente sulla stringa originaria 'accorciata di uno': per questo la stringa originaria viene ricopiata in un nuovo array tmp (9) il cui ultimo carattere viene cancellato ponendolo a '\0' in modo da accorciare la stringa tmp di uno (10). Il risultato della chiamata ricorsiva viene quindi appeso dopo il primo carattere della stringa risultato s_rib che stiamo costruendo (11).

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  6. #6
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Originariamente inviato da internet
    una soluzione potrebbe essere questa

    codice:
    void ribalta(char* s, int i, int j)
    {
      if (i < j)
      {
        /* scambia s[i] <-> s[j] */
        t = s[i]
        s[i] = s[j];
        s[j] = t;
        ribalta(s, i+1, j-1);
      }   
    }
    la chiamata
    codice:
    ribalta(s, 0, strlen(s)-1);
    Il problema di questa versione è che modifica la stringa originaria e ad esempio non può essere invocata su letterali stringa come:

    ribalta("ciao", 0, 3);

    perche in C i letterali stringa non possono essere modificati.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  7. #7
    era sottointeso che la stringa andasse ribaltata in loco visto che non è stato specificato, e comunque anche la funzione
    strrev() fa un revere inplace

    non vedo il motivo di crearne una nuova dalla funzione

    se c'è questa necessità e il cliente che se ne occupa

    in c++
    codice:
    std::string myString = "hello";
    std::reverse( myString.begin(), myString.end() );

  8. #8
    Utente di HTML.it L'avatar di Iena87
    Registrato dal
    Dec 2003
    Messaggi
    429
    Grazie mille

  9. #9
    quest'altra versione usa un parametro in meno

    codice:
    void ribalta(char* s, int n)
    {
      char t;
    
      if (n > 1)
      {
        t = s[0];
        s[0] = s[n-1];
        s[n-1] = t;
        ribalta(s+1, n-2);
      }   
    }
    la chiamata
    codice:
    ribalta(s, strlen(s));

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.