Premesso che
- non sono andato a riguardarmi il codice che ho scritto in passato;
- l'argomento “file I/O” mi mancava e ho appena letto velocemente qualcosina al riguardo;
- il mio PC è un rottame;
questo
+////
4
not_exists
++/++
2
++/++
1
ok
not_exists
/////
5
++/++
2
2rj9R
2rq9R
ok
+////
1
ok
Process returned 0 (0x0) execution time : 0.053 s
Press any key to continue.
è l'output che ottengo dal seguente codice
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define N 256
typedef struct nodo_
{
char *p;
char *res;
uint8_t SI[N];
uint8_t NO[N];
uint8_t u[N];
unsigned int u_dim;
int flag_comp;
struct nodo_ *next;
} nodo;
nodo* aggiungi_nodo_in_ordine(nodo **ptr, char *p, unsigned int k)
{
while(*ptr && strcmp((*ptr)->p, p) < 0)
{
ptr = &(*ptr)->next;
}
nodo *nuovo = (nodo*)malloc(sizeof(nodo));
nuovo->p = (char*)malloc(sizeof(char) * (k + 1));
strcpy(nuovo->p, p);
nuovo->res = (char*)malloc(sizeof(char) * (k + 1));
*nuovo->res = nuovo->res[k] = '\0';
nuovo->next = *ptr;
return(*ptr = nuovo);
}
nodo* trova_nodo(nodo *ptr, char *p)
{
int cmp = 1;
while(ptr && (cmp = strcmp(p, ptr->p)) > 0)
{
ptr = ptr->next;
}
return(!cmp ? ptr : NULL);
}
void definisci_alfabeto(uint8_t *alf)
{
for(char c = '0'; c <= '9'; ++alf[c++]);
for(char c = 'A'; c <= 'Z'; ++alf[c++]);
for(char c = 'a'; c <= 'z'; ++alf[c++]);
++alf['-'];
++alf['_'];
}
int verifica_parola_valida(char *p, uint8_t *alf, unsigned int k)
{
unsigned int i;
for(i = 0; i < k && alf[p[i]]; ++i);
return(i == k && !p[i]);
}
int verifica_parola_ammissibile(nodo **ptr, nodo *p_amm, char *p)
{
if(!(*ptr = trova_nodo(p_amm, p)))
{
printf(" not_exists\n");
}
return(*ptr != NULL);
}
int verifica_parola_compatibile(char *p2, nodo *nd_p)
{
uint8_t v[N] = {0};
unsigned int i;
for(i = 0; nd_p->p[i] && (nd_p->res[i] == '+' ? p2[i] == nd_p->p[i] : p2[i] != nd_p->p[i] && ++v[p2[i]] && (!nd_p->NO[p2[i]] || nd_p->SI[p2[i]] - v[p2[i]] >= 0)); ++i);
for(i = !nd_p->p[i] ? 0 : nd_p->u_dim + 1; i < nd_p->u_dim && v[nd_p->u[i]] - nd_p->SI[nd_p->u[i]] >= 0; ++i);
return(i == nd_p->u_dim);
}
void aggiungi_nuove_parole_ammissibili(FILE *f, nodo **p_amm, char *input, uint8_t *alf, unsigned int k, int flag_sequenza_iniziale, unsigned int n, unsigned int *n_p_comp)
{
while(1)
{
fscanf(f, " %s", input);
if(verifica_parola_valida(input, alf, k))
{
nodo *ptr = aggiungi_nodo_in_ordine(p_amm, input, k);
if(n && *n_p_comp)
{
nodo *temp = *p_amm;
while(temp && (!*temp->res || (ptr->flag_comp = verifica_parola_compatibile(ptr->p, temp))))
{
temp = temp->next;
}
*n_p_comp += !temp;
}
}
else if(flag_sequenza_iniziale ? *p_amm && !strcmp(input, "+nuova_partita") : !strcmp(input, "+inserisci_fine"))
{
break;
}
}
}
void nuova_partita(FILE *f, nodo **nd_r, nodo *p_amm, char *input, uint8_t *alf, unsigned int k, unsigned int *n, unsigned int *n_p_comp)
{
do
{
fscanf(f, " %s", input);
}
while(!verifica_parola_valida(input, alf, k) || !verifica_parola_ammissibile(nd_r, p_amm, input));
do
{
fscanf(f, "%u", n);
}
while(!*n);
while(p_amm)
{
*p_amm->res = '\0';
p_amm->flag_comp = 1;
p_amm = p_amm->next;
}
*n_p_comp = 0;
}
void stampa_filtrate(nodo *p_amm, unsigned int n_p_comp)
{
while(n_p_comp)
{
if(p_amm->flag_comp)
{
printf(" %s\n", p_amm->p);
--n_p_comp;
}
p_amm = p_amm->next;
}
}
void determina_stringa_confronto(char *r, nodo *nd_p)
{
memset(nd_p->SI, nd_p->u_dim = 0, sizeof(*nd_p->SI) * N);
memset(nd_p->NO, 0, sizeof(*nd_p->NO) * N);
uint8_t v[N] = {0};
for(unsigned int i = 0; r[i]; ++i)
{
if(nd_p->p[i] == r[i])
{
nd_p->res[i] = '+';
}
else
{
nd_p->res[i] = '/';
++v[r[i]];
}
}
for(unsigned int i = 0; r[i]; ++i)
{
if(nd_p->res[i] == '/')
{
if(v[nd_p->p[i]])
{
nd_p->res[i] = '|';
--v[nd_p->p[i]];
if(!nd_p->SI[nd_p->p[i]]++)
{
nd_p->u[(nd_p->u_dim)++] = nd_p->p[i];
}
}
else
{
++nd_p->NO[nd_p->p[i]];
}
}
}
}
void determina_parole_compatibili(nodo *p_amm, nodo *nd_r, nodo *nd_p, unsigned int *n_p_comp)
{
*n_p_comp = 0;
while(p_amm)
{
if(p_amm == nd_r || p_amm->flag_comp && (p_amm->flag_comp = verifica_parola_compatibile(p_amm->p, nd_p)))
{
++*n_p_comp;
}
p_amm = p_amm->next;
}
}
int main()
{
FILE *f = fopen("test.txt", "r");
if(f)
{
unsigned int k;
unsigned int n;
unsigned int n_p_comp;
nodo *p_amm = NULL;
nodo *nd_r;
nodo *nd_p;
char input[500];
uint8_t alf[N] = {0};
definisci_alfabeto(alf);
do
{
fscanf(f, "%u", &k);
}
while(!k);
aggiungi_nuove_parole_ammissibili(f, &p_amm, input, alf, k, 1, 0, &n_p_comp);
nuova_partita(f, &nd_r, p_amm, input, alf, k, &n, &n_p_comp);
while(!feof(f))
{
fscanf(f, " %s", input);
if(n && verifica_parola_valida(input, alf, k) && verifica_parola_ammissibile(&nd_p, p_amm, input))
{
if(nd_p == nd_r)
{
printf(" ok\n");
n = 0;
}
else
{
determina_stringa_confronto(nd_r->p, nd_p);
determina_parole_compatibili(p_amm, nd_r, nd_p, &n_p_comp);
printf(" %s\n %u\n", nd_p->res, n_p_comp);
if(!--n)
{
printf(" ko\n");
}
}
}
else if(n && !strcmp(input, "+stampa_filtrate"))
{
stampa_filtrate(p_amm, n_p_comp);
}
else if(!strcmp(input, "+inserisci_inizio"))
{
aggiungi_nuove_parole_ammissibili(f, &p_amm, input, alf, k, 0, n, &n_p_comp);
}
else if(!strcmp(input, "+nuova_partita"))
{
nuova_partita(f, &nd_r, p_amm, input, alf, k, &n, &n_p_comp);
}
else if(!strcmp(input, "+exit"))
{
break;
}
}
fclose(f);
return 0;
}
return -1;
}
ottenuto da quello qui postato sostituendo la lettura da standard input con quella da file (o almeno è quello che ho provato a fare visto i pochi minuti che ho dedicato alla cosa).
Ovviamente il test effettuato è l'ultimo che hai postato.