[C] Dubbio esercizio funzione ricorsiva

Messaggioda nick_10 » 25/11/2018, 12:19

Ciao! Di nuovo funzioni ricorsive...questa volta il mio programma dovrebbe andar (quasi) bene.
Volevo sapere da voi se poteva andare. Il testo è il seguente:
"Scrivere una funzione ricorsiva che
• legga in input una sequenza di caratteri alfabetici di lunghezza arbitraria, che termina quando viene immesso un carattere non alfabetico, e che
• stampi ogni carattere minuscolo e stampi invece ogni carattere maiuscolo solo se `e preceduto da un carattere minuscolo.
• restituisca il numero di elementi scartati
Se ad esempio la sequenza fosse b g R u C E F j P 9 la funzione dovrebbe stampare b g R u C j P e restituire 2."
Il problema è sempre il solito delle discussioni precedenti e come sempre mi sono appoggiato sul main per leggere il primo carattere che diventerà il carattere precedente nella ricorsione.
Però, per stamparlo l'unico modo che ho trovato è quello di farlo nel main. Ecco:
Codice:
#include <stdio.h>
int sequenzaalfabeticaric(char prev){
    char  c;
    scanf("%c",&c);
    if((c>='a' && c<='z')||(c>='A' && c<='Z')){
        if((c>='a' && c<='z')){
            printf("%c",c);
            return 0+sequenzaalfabeticaric(c);
        }
        else if((c>='A' && c<='Z')&&(prev>='a' && prev<='z')){
            printf("%c",c);
            return 0+sequenzaalfabeticaric(c);
        }
        else return 1+sequenzaalfabeticaric(c);
    }
    else{
        printf("Sequenza modificata: \n");
        return 0;
    }
}
int main() {
    char c;
    scanf("%c",&c);
    printf("%c",c);   //problema di stampa del primo valore
    printf("Il numero di elementi scartati è:%d\n",sequenzaalfabeticaric(c));
    return 0;
}
nick_10
Average Member
Average Member
 
Messaggio: 332 di 754
Iscritto il: 17/11/2016, 16:21

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda Super Squirrel » 25/11/2018, 16:20

Io farei qualcosa del genere:
Codice:
#include <iostream>

using namespace std;

int fun(bool prev_is_lower = false)
{
    char c;
    cout << "--> ";
    cin >> c;
    bool curr_is_upper = c >= 'A' && c <= 'Z';
    if(curr_is_upper || (c >= 'a' && c <= 'z'))
    {
        if(!(curr_is_upper && !prev_is_lower))
        {
            cout << c << endl;
        }
        return !prev_is_lower * curr_is_upper + fun(!curr_is_upper);
    }
    return 0;
}

int main()
{
    cout << "CARATTERI SCARTATI: " << fun();
}


EDIT:
P.S.
mi sembra strano che il codice che hai postato ti faccia effettuare più di 1 inserimento... la scanf() nella funzione dovrebbe essere "ignorata", nel senso che dovrebbe leggere il carattere newline presente nel buffer di inserimento.
Chi dorme in democrazia, si sveglia in dittatura.
Super Squirrel
Senior Member
Senior Member
 
Messaggio: 311 di 1486
Iscritto il: 16/05/2013, 22:05

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda vict85 » 25/11/2018, 17:12

Mi sfugge della richiesta se l'input è qualcosa del tipo AsaAABbScedjfnkanfsdM oppure se tra i caratteri ci sono gli spazi. Dal modo in cui il tutto verrebbe visualizzato suppongo che si debba implementare la prima versione. Usando una funzione di appoggio invece che una variabile si può fare così:
Codice:
#include "ctype.h"
#include "stdio.h"

int strange_read();
int strange_read_state_2();

int main(void)
{
    int scartati = strange_read();
    printf("\nscartati=%d", scartati);
}

int strange_read()
{
    int ch = getc(stdin);
    if (ch == EOF || !isalpha(ch))
    {
        return 0;
    }

    if (islower(ch))
    {
        putc(ch, stdout);
        return strange_read_state_2();
    }
    return 1 + strange_read();
}

int strange_read_state_2()
{
    int ch = getc(stdin);
    if (ch == EOF || !isalpha(ch))
    {
        return 0;
    }
    putc(ch, stdout);
    if (isupper(ch))
    {
        return strange_read();
    }
    return strange_read_state_2();
}

Di fatto ho implementato una sorta di automa.
vict85
Moderatore
Moderatore
 
Messaggio: 9438 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda nick_10 » 25/11/2018, 21:17

Grazie a entrambi per le risposte.
Molte delle cose scritte però non le comprendo :roll:
Forse perché non ho fatto molte delle cose che avete scritto, ad esempio l'uso di altre librerie
nick_10
Average Member
Average Member
 
Messaggio: 334 di 754
Iscritto il: 17/11/2016, 16:21

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda Super Squirrel » 26/11/2018, 00:50

In realtà il codice che ho postato non utilizza nessuna funzione/libreria particolare, semplicemente è scritto in C++.
Questa sarebbe la traduzione in C:
Codice:
#include <stdio.h>

int fun(int prev_is_lower)
{
    char c;
    printf("--> ");
    scanf(" %c", &c);
    int curr_is_upper = c >= 'A' && c <= 'Z';
    if(curr_is_upper || (c >= 'a' && c <= 'z'))
    {
        if(!(curr_is_upper && !prev_is_lower))
        {
            printf("%c\n", c);
        }
        return !prev_is_lower * curr_is_upper + fun(!curr_is_upper);
    }
    return 0;
}

int main()
{
    printf("CARATTERI SCARTATI: %d", fun(0));
    return 0;
}

o anche semplificando un po' la parte logica:
Codice:
#include <stdio.h>

int fun(int prev_is_lower)
{
    char c;
    printf("--> ");
    scanf(" %c", &c);
    int curr_is_upper = c >= 'A' && c <= 'Z';
    int curr_is_lower = c >= 'a' && c <= 'z';
    if(curr_is_upper || curr_is_lower)
    {
        if(curr_is_lower || (curr_is_upper && prev_is_lower))
        {
            printf("%c\n", c);
        }
        return !prev_is_lower * curr_is_upper + fun(curr_is_lower);
    }
    return 0;
}

int main()
{
    printf("CARATTERI SCARTATI: %d", fun(0));
    return 0;
}


Quasi dimenticavo... e per quanto riguarda la questione che ho sollevato nel P.S. del mio precedente post?
Chi dorme in democrazia, si sveglia in dittatura.
Super Squirrel
Senior Member
Senior Member
 
Messaggio: 312 di 1486
Iscritto il: 16/05/2013, 22:05

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda vict85 » 26/11/2018, 13:19

Quali funzioni non conosci del mio codice?
vict85
Moderatore
Moderatore
 
Messaggio: 9440 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda nick_10 » 26/11/2018, 22:35

@Super Squirrel per quanto riguarda il tuo P.S. , riesco a mettere più di un carattere perché l'input è da dare nella forma "idis" con tutte le lettere attaccate

@vict85 espressione del tipo "EOF" o "isalpha"...scusa la mia ignoranza ma mai incontrate :roll:
nick_10
Average Member
Average Member
 
Messaggio: 338 di 754
Iscritto il: 17/11/2016, 16:21

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda vict85 » 27/11/2018, 10:06

EOF sta per end of file, getc, getchar, fgetc e varie funzioni simili lo ritornano in caso di errore. Ha probabilmente più senso usarlo con i file. E siccome isalpha(EOF)==0 avrei anche potuto non metterlo.

isalpha, islower e isupper sono le funzioni dello standard per testare rispettivamente se un carattere è una lettera dell'alfabeto, se è minuscola e se è maiuscola. Se cerchi isalpha cppreference su Google ti trovi tutte le info (c'è la documentazione sia per il c++ che per il c).
vict85
Moderatore
Moderatore
 
Messaggio: 9442 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C] Dubbio esercizio funzione ricorsiva

Messaggioda nick_10 » 28/11/2018, 13:50

Grazie mille anche per gli spunti! Molto interessanti, ci studierò su
nick_10
Average Member
Average Member
 
Messaggio: 341 di 754
Iscritto il: 17/11/2016, 16:21


Torna a Informatica

Chi c’è in linea

Visitano il forum: utente__medio e 1 ospite