Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2006
    Messaggi
    156

    [C]notazione polacca inversa con variabili letterali e numeri con più cifre

    ho seri e gravi problemi a implementare un algoritmo per la notazione polacca inversa.

    avrei bisogno di quanto segue:
    data un'espressione infissa, trasformare la suddetta espressione in notazione polacca inversa. quindi eseguire il calcolo dell'espressione attraverso la nuova espressione scritta in notazione polacca inversa.

    avevo già da tempo scritto queste funzioni, ma ora devo eseguire delle modifiche che mi stanno facendo dannare.
    le funzioni da me scritte erano semplici, in quanto gli operandi dovevano essere numeri interi di una sola cifra.

    se volete vedere quello che avevo scritto andate ai seguenti link
    per trasformare un'espressione infissa in un'espressione postfissa (ossia in notazione polacca inversa) andate qui
    http://nopaste.simosnap.com/2468

    per vedere la funzione che che risolve il calcolo di un'espressione in notazione polacca inversa andate qui
    http://nopaste.simosnap.com/2469

    ora invece devo trattare anche quelle situazioni in cui gli operandi possono essere composti da più cifre e possono inoltre essere inserite anche variabili letterali (queste ultime di una sola lettera)

    tanto per fare un esempio
    codice:
    17 + y * 2

    come posso fare?
    ho pensato di suddividere le espressioni in token e atraverso la funzione atoi generare il corrispettivo intero per le costanti di stringa numeriche maggiori di una cifra (il 17 dell'esempio).
    ma ci sono una serie di problemi che non so risolvere.

    una volta che io ho trasformato tutti i token in interi, mi potrei trovare in una situazione di questo tipo:
    ecco un altro esempio per chiarire:
    codice:
    99 + c

    in questo caso la stringa che contiene 99 diventa un int con valore 99, ma se io converto anche c (per avere tutte le variabili dello stesso tipo) anche il valore ascii di c è 99...
    quindi quando io devo calcolare il risultato dell'espressione dalla notazione postfissa mi troverei in una situazione che non so più riconoscere la variabile c dall'intero 99... visto che tutti e due sono 99...

    miiiii, che casino!
    aiuto...

  2. #2

    Re: [C]notazione polacca inversa con variabili letterali e numeri con più cifre

    Originariamente inviato da ilmo lesto
    ho seri e gravi problemi a implementare un algoritmo per la notazione polacca inversa.

    avrei bisogno di quanto segue:
    data un'espressione infissa, trasformare la suddetta espressione in notazione polacca inversa. quindi eseguire il calcolo dell'espressione attraverso la nuova espressione scritta in notazione polacca inversa.

    avevo già da tempo scritto queste funzioni, ma ora devo eseguire delle modifiche che mi stanno facendo dannare.
    le funzioni da me scritte erano semplici, in quanto gli operandi dovevano essere numeri interi di una sola cifra.

    se volete vedere quello che avevo scritto andate ai seguenti link
    per trasformare un'espressione infissa in un'espressione postfissa (ossia in notazione polacca inversa) andate qui
    http://nopaste.simosnap.com/2468

    per vedere la funzione che che risolve il calcolo di un'espressione in notazione polacca inversa andate qui
    http://nopaste.simosnap.com/2469

    ora invece devo trattare anche quelle situazioni in cui gli operandi possono essere composti da più cifre e possono inoltre essere inserite anche variabili letterali (queste ultime di una sola lettera)

    tanto per fare un esempio
    codice:
    17 + y * 2

    come posso fare?
    ho pensato di suddividere le espressioni in token e atraverso la funzione atoi generare il corrispettivo intero per le costanti di stringa numeriche maggiori di una cifra (il 17 dell'esempio).
    ma ci sono una serie di problemi che non so risolvere.

    una volta che io ho trasformato tutti i token in interi, mi potrei trovare in una situazione di questo tipo:
    ecco un altro esempio per chiarire:
    codice:
    99 + c

    in questo caso la stringa che contiene 99 diventa un int con valore 99, ma se io converto anche c (per avere tutte le variabili dello stesso tipo) anche il valore ascii di c è 99...
    quindi quando io devo calcolare il risultato dell'espressione dalla notazione postfissa mi troverei in una situazione che non so più riconoscere la variabile c dall'intero 99... visto che tutti e due sono 99...

    miiiii, che casino!
    aiuto...
    Ciao,

    googlando ho trovato questo esempio, magari ti puo dare uno spunto. Buon lavoro!

    http://www.fredosaurus.com/notes-cpp...s/rpn/rpn.html

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2006
    Messaggi
    156
    ciao UltraBeginner,
    grazie per lo spunto, ma purtroppo il c++ ancora non lo mastico... pure io sto googlando, ma non riesco a trovare nulla.
    per la cronaca, dovrei implementare questi algoritmi per costruire un compilatore minimale che traduca le istruzioni di un linguaggio in alto livello (da me creato) in linguaggio macchina del Simpletron (anche questo da me creato). è uno degli ultimi esercizi del libro "C corso completo di programmazione" del DEITEL&DEITEL. magari qualcuno ha già avuto modo di affrontare questo esercizio...
    il problema è che essendo completamente autodidatta, i forum e i pochi amici programmatori sono le mie uniche risorse

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2006
    Messaggi
    258
    Allora, questo è un programma che abbiamo fatto a scuola (che ho leggermente modificato per fargli accettare anche i numeri).
    Lavora carattere per carattere... Tu vedi se devi modificare qualcosa... se ti serve qualcosa... basta che chiedi.

    Il testo dell'esercizio (con la spiegazione del metodo usato per risolvere il problema) è all'indirizzo
    http://ulisse.polito.it/matdid/3ing_...ti/EsMon07.txt

    e il codice è:

    codice:
    #include<stdio.h>
    #include<ctype.h>
    #include<stdlib.h>
    #include<math.h>
    #include<string.h>
    #define MAX_STRINGA 30
    #define NON_PRESENTE -1
    int matr_regole[6][7]={{4,1,1,1,1,1,5},
    			{2,2,2,1,1,1,2},
    			{2,2,2,1,1,1,2},
    			{2,2,2,2,2,1,2},
    			{2,2,2,2,2,1,2},
    			{5,1,1,1,1,1,3}};
    char vett_car[7+1]="%+-*/()";
    
    typedef struct dato_s
    {
    	char carat;
    	struct dato_s *prossimo;
    }dato;
    typedef enum {FALSE,TRUE} boolean;
    
    dato *stack_pointer,*punt_insert,*punt_extract;
    char str[MAX_STRINGA];
    int indice,colonna,riga,regola;
    boolean finito,corretto;
    char carat_stack;
    
    int leggi_str(char stringa[]);
    void push(dato **p_stack_pointer, char carattere);
    void pop(dato **p_stack_pointer, char *carattere);
    void queue(dato **p_insert, dato **p_extract, char carattere);
    int cerca_posizione(char carattere);
    void guarda_cima_stack(dato *p_stack_pointer, char *carattere);
    void stampa(dato *punt);
    void inizializza (dato **p_stack_pointer, dato **p_punt_insert, dato **p_punt_extract);
    
    main()
    {
    	clrscr();
    	while(leggi_str(str)!=EOF)
    	{
    		inizializza (&stack_pointer,&punt_insert,&punt_extract);
    		push(&stack_pointer,str[0]);
    		indice=1;
    		finito=FALSE;
    		while(!finito)
    		{
    			if((colonna=cerca_posizione(str[indice]))==NON_PRESENTE)
    			{
    				queue(&punt_insert,&punt_extract,str[indice]);
    				indice++;
    			}
    			else
    			{
    				guarda_cima_stack(stack_pointer,&carat_stack);
    				riga=cerca_posizione(carat_stack);
    				regola=matr_regole[riga][colonna];
    				switch(regola)
    				{
    					case 1:
    					{
    						push(&stack_pointer,str[indice]);
    						indice++;
    					}
    					break;
    					case 2:
    					{
    						pop(&stack_pointer,&carat_stack);
    						queue(&punt_insert,&punt_extract,carat_stack);
    					}
    					break;
    					case 3:
    					{
    						pop(&stack_pointer,&carat_stack);
    						indice++;
    					}
    					break;
    					case 4:
    					{
    						corretto=TRUE;
    						finito=TRUE;
    					}
    					break;
    					case 5:
    					{
    						corretto=FALSE;
    						finito=TRUE;
    					}
    				}
    			}
    		}
    		if(corretto)
    			stampa(punt_extract);
    		else
    			printf("Espressione non correttamente bilanciata\n");
    	}
    }
    
    
    void inizializza (dato **p_stack_pointer, dato **p_punt_insert, dato **p_punt_extract)
    {
    dato *p_aux, *p_prec;
    
    p_aux = *p_stack_pointer;
    while (p_aux!=NULL)
    	{
    	p_prec = p_aux;
    	p_aux = (*p_prec).prossimo;
    	free (p_prec);
    	}
    *p_stack_pointer=NULL;
    *p_punt_insert=*p_punt_extract=NULL;
    }
    
    
    
    
    int leggi_str(char stringa[])
    {
    	int indice;
    	char carat;
    	stringa[0]='%';
    	indice=1;
            printf("Introduci l'espressione infissa (CTRL+Z per terminare): ");
    	while(((carat=getchar())!='\n')&&(carat!=EOF))
    	{
    		stringa[indice]=carat;
    		indice++;
    	}
    	stringa[indice]='%';
    	stringa[indice+1]='\0';
    	return(carat);
    }
    
    void push(dato **p_stack_pointer, char carattere)
    {
    	dato *p_corr;
    	p_corr=(dato *)malloc(sizeof(dato));
    	(*p_corr).carat=carattere;
    	(*p_corr).prossimo=*p_stack_pointer;
    	*p_stack_pointer=p_corr;
    }
    
    void pop(dato **p_stack_pointer, char *carattere)
    {
    	*carattere=(**p_stack_pointer).carat;
    	*p_stack_pointer=(**p_stack_pointer).prossimo;
    }
    
    void queue(dato **p_insert, dato **p_extract, char carattere)
    {
    	dato *p_corr;
    	p_corr=(dato *)malloc(sizeof(dato));
    	(*p_corr).carat=carattere;
    	(*p_corr).prossimo=NULL;
    	if(*p_insert==NULL)
    	{
    		*p_insert=p_corr;
    		*p_extract=p_corr;
    	}
    	else
    	{
    		(**p_insert).prossimo=p_corr;
    		*p_insert=p_corr;
    	}
    }
    
    int cerca_posizione(char carattere)
    {
    	int indice=0;
    	while((vett_car[indice]!=carattere)&&(indice<strlen(vett_car)))
    		indice++;
    	if (indice==strlen(vett_car))
    		indice = NON_PRESENTE;
    	return(indice);
    }
    
    void guarda_cima_stack(dato *p_stack_pointer, char *carattere)
    {
    	*carattere=(*p_stack_pointer).carat;
    }
    
    void stampa(dato *punt)
    {
    	dato *p_temp;
    	p_temp=punt;
    	while(p_temp!=NULL)
    	{
    		putchar((*p_temp).carat);
    		p_temp=(*p_temp).prossimo;
    	}
    	putchar('\n');
    }
    Ciao!

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2006
    Messaggi
    156
    innanzitutto grazie per l'esempio!
    ho notato che oltre allo stack per immagazzinare gli operatori, hai anche utilizzato una coda per l'espressione finale (cosa che io non ho fatto)
    inoltre ho visto che hai utilizzato una matrice per gestire i vari casi in cui si potrebbe incorrere...

    Originariamente inviato da frarugi87

    Lavora carattere per carattere...
    il mio problema è proprio questo!
    ho guardato il codice e mi sono reso conto che attraverso la tua implementazione puoi gestire numeri o lettere di una cifra (correggimi se sbaglio), ma se io volessi mettere un numero composto da + di una cifra sono punto e a capo.

    rifacendomi all'esercizio che avevo fatto, il DEITEL mi consigliava di utilizzare dei token per isolare operatori e operandi, dopodichè mi diceva di utilizzare la funzione atoi per convertire le costanti di stringa. (il testo dell'esercizio però non è molto chiaro IMHO)

    dal momento che io converto con atoi una stringa numerica in un int, mi ritrovo a dover lavorare con degli int, e quindi anche gli altri caratteri dovrebbero essere convertiti... e qui, purtroppo, comincio a perdermi...

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2006
    Messaggi
    258
    Beh, per ora mi sono venute in mente un paio di idee per risolvere il tuo problema:

    potresti memorizzare i numeri come int, riservando 26 numeri (ad esempio gli ultimi 26) alle lettere. Cioè se incontri la lettera A la memorizzi come 32676 (non so neanche se è giusto come valore... ho tirato a caso)

    oppure potresti memorizzare i dati in una struct, definendola ad es così:

    typedef struct
    {
    int valore_numerico;
    char carattere;
    } dato;

    e mettendo in carattere un valore arbitrario (puoi usare '@' o qualsiasi altro carattere) se si è memorizzato un numero.

    Se vuoi provo a pensarci su a come farlo... se invece vuoi metterti alla prova... fammi poi sapere come è venuto

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2006
    Messaggi
    156
    credo di risolvere in questo modo: tratto tutti i token come se fossero stringhe, quindi senza nessun tipo di conversione... dichiaro nella stack struct un vettore di caratteri preposto a contenere sia cifre che variabili, anzichè utilizzare un semplice dato char. a questo punto posso scambiare qualsiasi cosa perchè non ho più problemi di lunghezze o trasformazioni...

    a dire il vero avevo pensato anche a una soluzione del tuo tipo, ma mi dava l'impressione di "barare", non mi sembra che sia una cosa pulita al 100%...

    grazie e vi farò sapere... se avete idee migliori non esitate a postare!

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2006
    Messaggi
    258
    giusto.... basta mettere una stringa e sei a posto... Come al solito le soluzioni semplici sono quelle che non mi vengono in mente... lo dice sempre anche il prof di fisica.... ;-) Ciao!

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.