migliorabile ha scritto:
Usi uno stack:
ogni volta che incontri un valore, lo inserisci sullo stack
ogni volta che incontri un operatore, controlli se nello stack ci sono abbastanza operandi (altrimenti generi errore), esegui l'operazione (che puo' generare errore) ed inserisci il risultato sullo stack
Si chiama RPN (Reverse Polish Notation) ed e' il modo (superiore ) con cui si utilizzano le calcolatrici Hewlett Packard, al contrario delle calcolatrici Texas ( ) che usano il SOA (Sistema Operativo Algebrico)
Oh, no, non si tratta di risolvere un'operazione in postfissa, quello l'ho già fatto: devo solo trovare un modo per validarla, cioè controllare che l'utente non metta una formula a caso!
vbextreme ha scritto:
piu modalità dai all'utente di inserire la formula e piu modalità dovrai gestire.
Per questo nell'altro thread avevo proposto la classica infissa e poi trasformarla in postfissa.(cosa piu logica per l'utente e per il programma.)
Posta il codice poi vediamo come fare.
Questo è il codice relativo alla validazione, ma ti avverto, prenderai paura...
int valida_formula(elem_form_t formula){
int i, /* variabile usata come contatore */
right, /* variabile usata come contatore */
err = 0, /* variabile che controlla la presenza di errori */
num = 0, /* variabile usata per contare il numero di proposizioni */
alpha = 0, /* variabile usata per contare il numero di connettivi binari */
connettivi = 0, /* variabile usata per contare il numero di conettivi generici */
cont = 0;
size_t num_elem; /* variabile usata per calcolare la lunghezza della formula */
/* conta il numero di elementi della formula e li
memorizza nella variabile num_elem */
num_elem = strlen(&formula.nome);
/* controlla che la formula non ecceda il numero di caratteri massimo
e nel caso, stampa un messaggio di errore e aggiorna err*/
if (num_elem > 7)
{
printf("\nERRORE: la formula e' troppo lunga!\n");
err++;
}
/* primo controllo sulla formula */
for (i = 0; i < num_elem; i++){
/* controlla che i singoli caratteri inseriti siano numeri da 1 a 4 o lettere,
in caso contrario, stampa un messaggio di errore e aggiorna err */
if (ispunct(formula.nome[i]))
{
err++;
printf("\nERRORE: il carattere %c non e' valido!\n", formula.nome[i]);
}
/* conta il numero di connettivi logici binari e proposizioni */
if (isdigit(formula.nome[i]))
num++;
else if (isalpha(formula.nome[i]))
alpha++;
if (isdigit(formula.nome[i]))
if (formula.nome[i] > '4' || formula.nome[i] == '0')
{
err++;
printf("\nERRORE: %c non e' un connettivo logico valido!\n", formula.nome[i]);
}
if (isdigit(formula.nome[i]) && isdigit(formula.nome[i - 1]))
for(right = (i + 1); right < num_elem; right++)
if (isalpha(formula.nome[right]))
{
printf("\nERRORE: l'ordine dei connettivi/proposizioni è errato!\n");
err++;
}
}
if(isdigit(formula.nome[0]) || isalpha(formula.nome[strlen(formula.nome) - 1]))
{
printf("\nERRORE: la formula deve iniziare con una\n\tproposizione e finire con un connettivo!\n");
err++;
}
/* controlla che il numero di conettivi logici binari
sia corretto rispetto al numero di proposizioni inserite */
if (isdigit(formula.nome[1]))
if(isalpha(formula.nome[0]))
cont++;
if ((alpha - num) != 1 || cont != 0)
{
printf("\nERRORE: il numero di connettivi logici binari non\n\te'corretto rispetto al numero di proposizioni!\n");
err++;
}
/* la formula è corretta: esegue l'ultimo controllo sul numero massimo di connettivi */
for (i = 0; i <= num_elem; i++)
{
if (isupper(formula.nome[i]))
connettivi++;
if (isdigit(formula.nome[i]))
connettivi++;
}
if (connettivi > 3)
printf ("Hai inserito %d connettivi logici su un massimo di 3\nripeti inserimento -> ", connettivi);
return err;
}
e questo è tutto il codice nel caso tu voglia provarlo:
/* inclusone delle librerie standard del sorgente */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
/* struttura dati definita per memorizzare le proposizioni
inserite dall'utente e i connettivi logici */
typedef struct elem_form
{
char nome[7];
int prop[7][16];
} elem_form_t;
/* struttura dati definita come una pila per lavorare sulla formula */
typedef struct elem_stack
{
int valore[16];
struct elem_stack *succ_p;
} elem_stack_t;
/* dichiarazione delle funzioni del programma */
elem_form_t acquisisci_formula();
int valida_formula();
void valori_formula(elem_form_t *formula);
int confronto_formule(elem_form_t *prima_formula, elem_form_t *seconda_formula);
void risolvi_formula(elem_form_t *formula, int risultato[]);
int main() {
elem_form_t prima_formula,
seconda_formula;
int i,
contr = 0,
risultato1[16],
risultato2[16];
printf("***************************************************\n");
printf("Programma che acquisisce due proposizioni logiche e \nstabilisce se esse sono equivalenti\n");
printf("Autore: Cocon Tommaso\n");
printf("***************************************************\n\n");
printf ("-Utilizza le lettere minuscole dell'alfabeto come proposizioni\n\n");
printf ("-Se desideri anteporre il connettivo logico di negazione\n utilizza la lettera MAIUSCOLA [p.e. not(a) = A]\n\n");
printf("Inserisci:\n");
printf ("\t1 per il connettivo logico di congiunzione\n\n");
printf ("\t2 per il connettivo logico di disgiunzione\n\n");
printf ("\t3 per il connettivo logico di implicazione\n\n");
printf ("\t4 per il connettivo logico di doppia implicazione\n\n");
printf ("Esempio di formula ben formata: ab2cd24\n\n");
printf("Inserire la prima proposizione logica -> ");
prima_formula = acquisisci_formula();
printf("Inserire la seconda proposizione logica -> ");
seconda_formula = acquisisci_formula();
valori_formula(&prima_formula);
valori_formula(&seconda_formula);
risolvi_formula(&prima_formula, risultato1);
risolvi_formula(&seconda_formula, risultato2);
for (i = 0; i < 16; i++)
if (risultato1[i] != risultato2[i])
contr++;
if (contr > 0)
printf("\nLe formule non sono equivalenti.\n");
else
printf("\nle formule sono equivalenti.\n");
return 0;
}
elem_form_t acquisisci_formula(){
/* dichiarazione delle variabili locali */
/* variabile contatore */
int err = 0;
elem_form_t formula; /* struttura che contiene le formula */
do
{
scanf("%s", formula.nome);
err = valida_formula(formula);
if (err != 0)
printf("\n\nSono stati riscontrati %d errori complessivi,\nripetere inserimento -> ", err);
}
while (err != 0);
return formula;
}
int valida_formula(elem_form_t formula){
int i, /* variabile usata come contatore */
right, /* variabile usata come contatore */
err = 0, /* variabile che controlla la presenza di errori */
num = 0, /* variabile usata per contare il numero di proposizioni */
alpha = 0, /* variabile usata per contare il numero di connettivi binari */
connettivi = 0, /* variabile usata per contare il numero di conettivi generici */
cont = 0;
size_t num_elem; /* variabile usata per calcolare la lunghezza della formula */
/* conta il numero di elementi della formula e li
memorizza nella variabile num_elem */
num_elem = strlen(&formula.nome);
/* controlla che la formula non ecceda il numero di caratteri massimo
e nel caso, stampa un messaggio di errore e aggiorna err*/
if (num_elem > 7)
{
printf("\nERRORE: la formula e' troppo lunga!\n");
err++;
}
/* primo controllo sulla formula */
for (i = 0; i < num_elem; i++){
/* controlla che i singoli caratteri inseriti siano numeri da 1 a 4 o lettere,
in caso contrario, stampa un messaggio di errore e aggiorna err */
if (ispunct(formula.nome[i]))
{
err++;
printf("\nERRORE: il carattere %c non e' valido!\n", formula.nome[i]);
}
/* conta il numero di connettivi logici binari e proposizioni */
if (isdigit(formula.nome[i]))
num++;
else if (isalpha(formula.nome[i]))
alpha++;
if (isdigit(formula.nome[i]))
if (formula.nome[i] > '4' || formula.nome[i] == '0')
{
err++;
printf("\nERRORE: %c non e' un connettivo logico valido!\n", formula.nome[i]);
}
if (isdigit(formula.nome[i]) && isdigit(formula.nome[i - 1]))
for(right = (i + 1); right < num_elem; right++)
if (isalpha(formula.nome[right]))
{
printf("\nERRORE: l'ordine dei connettivi/proposizioni è errato!\n");
err++;
}
}
if(isdigit(formula.nome[0]) || isalpha(formula.nome[strlen(formula.nome) - 1]))
{
printf("\nERRORE: la formula deve iniziare con una\n\tproposizione e finire con un connettivo!\n");
err++;
}
/* controlla che il numero di conettivi logici binari
sia corretto rispetto al numero di proposizioni inserite */
if (isdigit(formula.nome[1]))
if(isalpha(formula.nome[0]))
cont++;
if ((alpha - num) != 1 || cont != 0)
{
printf("\nERRORE: il numero di connettivi logici binari non\n\te'corretto rispetto al numero di proposizioni!\n");
err++;
}
/* la formula è corretta: esegue l'ultimo controllo sul numero massimo di connettivi */
for (i = 0; i <= num_elem; i++)
{
if (isupper(formula.nome[i]))
connettivi++;
if (isdigit(formula.nome[i]))
connettivi++;
}
if (connettivi > 3)
printf ("Hai inserito %d connettivi logici su un massimo di 3\nripeti inserimento -> ", connettivi);
return err;
}
void valori_formula(elem_form_t *formula){
int i; /* variabile contatore */
int modulo, risultato = 0, j, k, num_elem, cont_prop = 0;
num_elem = strlen(formula->nome);
for (i = 0, modulo = 2; i < num_elem; i++){
if (isalpha(formula->nome[i]))
{
for (j = 0; j < 16; j++){
risultato = j % modulo;
if (cont_prop == 0){
if (risultato == 0){
formula->prop[i][j] = 0;
}
else if (risultato == 1){
formula->prop[i][j] = 1;
}
}
else if (cont_prop == 1){
if (risultato < 2){
formula->prop[i][j] = 0;
}
else if (risultato >= 2){
formula->prop[i][j] = 1;
}
}
else if (cont_prop == 2){
if (risultato < 4){
formula->prop[i][j] = 0;
}
else if (risultato >= 4){
formula->prop[i][j] = 1;
}
}
else if (cont_prop == 3){
if (risultato < 8){
formula->prop[i][j] = 0;
}
else if (risultato >= 8){
formula->prop[i][j] = 1;
};
}
}
cont_prop++;
modulo *= 2;
}
}
for (i = 0; i < num_elem; i++)
if (isalpha(formula->nome[i]))
{
for (k = (i + 1); k < num_elem; k++)
{
if (tolower(formula->nome[i]) == tolower(formula->nome[k])){
for (j = 0; j < 16; j++)
formula->prop[k][j] = formula->prop[i][j];
}
}
}
for (i = 0; i < num_elem; i++)
if(isalpha(formula->nome[i]) && isupper(formula->nome[i]))
{
for (j = 0; j < 16; j++)
if (formula->prop[i][j] == 0)
formula->prop[i][j] = 1;
else
formula->prop[i][j] = 0;
}
}
void risolvi_formula(elem_form_t *formula, int risultato[]){
elem_stack_t *cima_p,
*pila_p;
int i, ris,
j, k,
val;
int op[2][16];
for (i = 0, j = 0; i < strlen(formula->nome); i++)
{
if(isalpha(formula->nome[i]))
{
j++;
pila_p = (elem_stack_t *)malloc(sizeof(elem_stack_t));
for (val = 0; val < 16; val++)
pila_p->valore[val] = formula->prop[i][val];
pila_p->succ_p = cima_p;
cima_p = pila_p;
}
else if (isdigit(formula->nome[i]))
{
for (k = 0; k < 2; k++)
{
for (val = 0; val < 16; val++)
op[k][val] = cima_p->valore[val];
if (cima_p != NULL)
cima_p = cima_p->succ_p;
}
pila_p = (elem_stack_t *)malloc(sizeof(elem_stack_t));
for (val = 0; val < 16; val++)
{
if (formula->nome[i] == '1'){
if (op[1][val] || op[0][val]){
ris = 1;
}
else{
ris = 0;
}
}
else if (formula->nome[i] == '2')
{
if (op[1][val] && op[0][val]){
ris = 1;
}
else{
ris = 0;
}
}
else if (formula->nome[i] == '3')
{
if (op[1][val] == 1 && op[0][val] == 0){
ris = 0;
}
else{
ris = 1;
}
}
else if (formula->nome[i] == '4')
{
if (op[1][val] == op[0][val]){
ris = 1;
}
else{
ris = 0;
}
}
pila_p->valore[val] = ris;
}
pila_p->succ_p = cima_p;
cima_p = pila_p;
}
}
for (i = 0; i < 16; i++)
risultato[i] = cima_p->valore[i];
}