PDA

View Full Version : [C] Notazione Polacca


xbubbax
17-03-2008, 17:59
Devo fare un programma utilizzando le pile che calcoli il risultato di una stringa in notazione polacca, tipo 34534+-* una cosa del genere

come faccio però a creare una stringa e dire al programma che per esempio se la stringa è 213 deve leggere 21 anzichè 2 e 1 separatamente?

gugoXX
17-03-2008, 18:20
Puoi decidere che il tuo "Motore" di calcolo accetta stringhe i cui elementi sono tutti separati da spazio.

xbubbax
17-03-2008, 18:50
non si può fare una cosa tipo char s[10]={'21','23','432','+','-'}

???

gugoXX
17-03-2008, 18:51
Certo... dipende da cosa hai in input.
Alla fine devi mettere il tutto in una pila comunque, mi sembra di aver capito

xbubbax
17-03-2008, 20:23
come posso fare nell'if per verificare se l'elemento della stringa è un numero oppure se è un simbolo(+,-,*,/)?

non posso usare il codice ascii perchè se il numero è a 2 o piu cifre cosa confronto?

#include <stdio.h>
#include <stdlib.h>
#include "funzioni_pile"

int Polacca(char s[], int n){

int op1=0;
int op2=0;
int operatore=0;
int somma=0;

pilaPtr P=NULL;
int i=0;

for(i=0;i<10;i++){
if(s[i]=OPERANDO){P=Push(P,OPERANDO);}
if(s[i]=OPERATORE){
operatore=s[i];
op1=Top(P);
P=Pop(P);
op2=Top(P);
P=Pop(P);

somma=op1 operatore op2;
P=Push(P,somma);}}





int main(void){

char s[10]={'20','15','100','5','-','*','+','21','-','\0'}

int Polacca(s[], 10);


system("PAUSE");}

xbubbax
17-03-2008, 20:28
l'algoritmo dovrebbe essere giusto, non so come fare quei confronti...

marko.fatto
17-03-2008, 20:51
non ti converrebbe leggere una stringa con spazi e usare quelli come delimitatori? :stordita:

edit:anche perchè se memorizzi i numeri come carattere non vai sopra il byte se non erro :stordita:

Abadir_82
17-03-2008, 20:56
Il mio progetto di info2 era proprio un calcolatore per matrici che implementava uno stack e DOVEVA usare la notazione polacca.

Sono passati 4 anni, non so se lo ho ancora, ma se lo trovo te lo mando, così puoi dare un'occhiata al codice.

gugoXX
17-03-2008, 21:04
come posso fare nell'if per verificare se l'elemento della stringa è un numero oppure se è un simbolo(+,-,*,/)?

non posso usare il codice ascii perchè se il numero è a 2 o piu cifre cosa confronto?

Guarda il primo carattere di ciascuna stringa
s[i][0]

xbubbax
17-03-2008, 21:07
quindi come potrei correggere, cioè come potrei fare il confronto? non ho capito bene

xbubbax
17-03-2008, 21:08
ti ringrazio abadir ma io ho anche la soluzione di questo esercizio ma è fatta leggermente diversa,al limite do un'occhiata a quella. se mi mandi il progetto sto 3 anni a leggerlo, grazie comq

gugoXX
17-03-2008, 21:11
quindi come potrei correggere, cioè come potrei fare il confronto? non ho capito bene

Per intanto ti invito ad indentare correttamente il codice, perche' cosi' e' davvero difficile da leggere.
Immagina di avere altre 2 o 3 livelli di indentazione e diventa un 400 colonne... non lo stampi piu' neppure se trovi le modulo continuo messe in orizzontale.


switch(s[i][0])
{
case '+':
case '-':
case '*':
case '/':
//operatore
break;
case '0':
case '1':
....
case '9':
//numero
break;
default:
//THROW PARSING ERROR
break;
}

marko.fatto
17-03-2008, 21:17
Guarda il primo carattere di ciascuna stringa
s[i][0]

ma come l'ha dichiarata lui è un'unica stringa..

che poi non dovrebbe nemmeno funzionare dato che non esiste il carattere '15' o '100' ecc..

ad esempio provando a stampare il carattere 15 ( cout<<'15' ) a me da 12597 :fagiano:

gugoXX
17-03-2008, 21:21
ma come l'ha dichiarata lui è un'unica stringa..


non mi sembra
Ha solo sbagliato a dichiarare qualcosina...
Comunque a me sarebbe piaciuto di piu' lo stringone separato da spazi

xbubbax
17-03-2008, 21:32
grazie, domani provo un po con i vostri metodi

marko.fatto
17-03-2008, 21:37
non mi sembra
Ha solo sbagliato a dichiarare qualcosina...
:mbe:
Comunque a me sarebbe piaciuto di piu' lo stringone separato da spazi

condivido :D

xbubbax
18-03-2008, 12:31
Ho provato a farlo un po a modo mio prendendo però le cifre singole dalla stringa, se funziona con le cifre singole funziona anche prendendo doppie cifre, basta solo cambiare qualcosa, tipo usare gli spazi come dite voi..

però mi da errore questo anche se sembra perfetto

#include <stdio.h>
#include <stdlib.h>
#include "funzioni_pile.h"

int Polacca(char *s){

pilaPtr P=NULL;
char c;
int op1=0;
int op2=0;
int risultato=0;

while(c=*s++){
if(c!='+' && c!='*'){
if(c!='-' && c!='/'){
P=Push(P,c-'0');}}else{
op1=Pop(P);
op2=Pop(P);
switch(c){
case'+':P=Push(P,op1+op2);break;
case'-':P=Push(P,op1-op2);break;
case'/':P=Push(P,op1/op2);break;
case'*':P=Push(P,op1*op2);break;}}}
risultato=Pop(P);
return risultato;}





int main(void){

char *s="345+*6-";

printf("%d\n", Polacca(s));

system("PAUSE");}

gugoXX
18-03-2008, 12:54
Perdonami, ma non si capisce nulla.
Proprio nulla.

Una riga cosi' e' illeggibile

P=Push(P,c-'0');}}else{

xbubbax
18-03-2008, 13:09
va meglio?

#include <stdio.h>
#include <stdlib.h>
#include "funzioni_pile.h"

int Polacca(char *s){

pilaPtr P=NULL;
char c;
int op1=0;
int op2=0;
int risultato=0;

while(c=*s++){
if(c!='+' && c!='*'){
if(c!='-' && c!='/'){
P=Push(P,c-'0');}}else{
op1=Pop(P);
op2=Pop(P);
switch(c){
case'+':P=Push(P,op1+op2);break;
case'-':P=Push(P,op1-op2);break;
case'/':P=Push(P,op1/op2);break;
case'*':P=Push(P,op1*op2);break;}}}
return Pop(P);}




int main(void){

char *s="345*+2-";

printf("%d\n", Polacca(s));

system("PAUSE");}

gugoXX
18-03-2008, 13:14
va meglio, ma se non ti piace avere righe con solo } parentesi graffe chiuse, dovrai scegliere altri linguaggi.
Lo standard dei costrutti con le parentesi graffe e'

Controllore di flusso
{
//Qualcosa
}

con una parentesi graffa dopo il controllore di flusso, a pari indentazione
e una parentesi graffa finale, per terminare il controllore di flusso, sempre a pari indentazione.

Comunque un errore logico che mi salta subito agli occhi e'

char *s="345*+2-";


Come fa un automa a capire quali sono i numeri su cui effettuare i conti?

xbubbax
18-03-2008, 13:18
in che senso parentesi aperte e chiuse? mi puoi dire dove ho fatto quest'errore, non lo trovo

beh, è semplice, prende carattere per carattere, se è un numero lo inserisce nella pila se è un operatore effettua l'operazione, non capisco che vuoi dire

gugoXX
18-03-2008, 13:23
in che senso parentesi aperte e chiuse? mi puoi dire dove ho fatto quest'errore, non lo trovo

beh, è semplice, prende carattere per carattere, se è un numero lo inserisce nella pila se è un operatore effettua l'operazione, non capisco che vuoi dire

Non e' un errore di programmazione.
Non sei semplicemente "Compliant" con lo standard di scrittura del codice.
O scriverai sempre codice da solo per te stesso, o appena dovessi lavorare insieme ad altri dovrete scegliere uno stile di programmazione.
Se questo stile di programmazione dovesse essere quello standard, meglio per voi e meglio per tutti.
Nello standard le parentesi graffe stanno da sole, senza null'altro su quella riga. Con la giusta indentazione.

Comunque se scrivo semplicemente

1234567+

Quale operazione voglio fare?
1+234567
oppure
12+34567
oppure
123+4567

Poiche' e' indecidibile da una macchina, stai abbracciando una soluzione sbagliata.

xbubbax
18-03-2008, 13:34
nono dovrei anche controllare se la stringa è scritta in modo corretto, ma vorrei fare prima un prova per controllare se funziona, però mi da errore sulla pila p, dice che non è dichiarata, cose del genere. ora ti incollo anche il file "funzioni_pile.h"

#include <stdio.h>
#include <stdlib.h>

int Empty(pilaPtr P){

if(P==NULL){return 1;}else{
return 0;}}

pilaPtr Push(pilaPtr P, int e){

pilaPtr temp=NULL;

temp=(pilaPtr)malloc(sizeof(nodo));
if(temp){
temp->dato=e;
temp->next=P;
P=temp;}else{
printf("MEMORIA PIENA\n");}}

pilaPtr Top(pilaPtr P){

return P;}

int Pop(pilaPtr P){

pilaPtr temp=NULL;
int el=0;

if(!Empty(P)){
temp=P;
el=P->data;
P=temp->next;
free(temp);
return el;}else{
printf("LA PILA GIA' E' VUOTA\n");}}

theking00
18-03-2008, 20:15
Ciao,
scusatemi ma non ho resistito ... usi veramente uno bruttissimo stile di coding, oltre alle indentazioni (:sofico: ) fai proprio un cattivissimo uso delle parentesi (blocchi).
guarda questo, e dimmi se non si legge molto meglio:


#include <stdio.h>
#include <stdlib.h>

int Empty(pilaPtr P)
{
if(P==NULL) return 1;
else return 0;
}

pilaPtr Push(pilaPtr P, int e)
{
pilaPtr temp = (pilaPtr)malloc( sizeof(nodo) );

if( temp )
{
temp->dato = e;
temp->next = P;
P = temp;
}
else
printf("MEMORIA PIENA\n");
}

pilaPtr Top(pilaPtr P)
{
return P;
}

int Pop(pilaPtr P)
{
pilaPtr temp = NULL;
int el = 0;

if( !Empty(P) )
{
temp = P;
el = P->data;
P = temp->next;
free(temp);
return el;
}
else
printf("LA PILA GIA' E' VUOTA\n");
}


cioè, prendiamo in esempio solo questa:


int Empty(pilaPtr P){

if(P==NULL){return 1;}else{
return 0;}}


non si capisce nulla (e penso che anche tu farai fatica), scrivendolo cosi invece:


int Empty(pilaPtr P)
{
if(P==NULL) return 1;
else return 0;
}


penso sia molto meglio sia per te che per che dovra leggerlo !