Implementa una cerca lineal per trobar un nom de proteïna en un array de structs. Si la troba, mostra'n la longitud.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf() i scanf() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strcmp() i strlen() */
/* Definició de l'estructura Proteina */
/* Una struct agrupa dades relacionades d'un mateix concepte */
struct Proteina { /* 'struct Proteina' és el nom complet del tipus */
char nom[50]; /* Nom o identificador de la proteïna */
/* Array de 50 caràcters (49 útils + '\0') */
char sequencia[200]; /* Seqüència d'aminoàcids */
/* Array de 200 caràcters per a la seqüència */
int longitud; /* Longitud de la seqüència (calculada) */
};
/* Funció de cerca lineal en un array de proteïnes */
/* Busca una proteïna pel seu nom i retorna la seva posició (índex) */
/* Retorna -1 si no la troba */
int cerca_lineal(struct Proteina array[], int mida, const char* nom_buscat){
/* Paràmetres:
- array[]: array d'estructures Proteina on buscar
- mida: nombre d'elements de l'array
- nom_buscat: cadena amb el nom a buscar (const: no es modificarà)
Retorna: índex de la proteïna trobada o -1 */
/* Bucle de cerca lineal: recorre l'array element per element */
for(int i = 0; i < mida; i++){ /* Itera des de l'índex 0 fins a mida-1 */
/* Compara el nom de la proteïna actual amb el nom buscat */
/* strcmp() compara dues cadenes alfabèticament */
/* Retorna 0 si són IGUALS */
if(strcmp(array[i].nom, nom_buscat) == 0){
/* Si els noms coincideixen, retorna l'índex on s'ha trobat */
return i; /* 'return' finalitza la funció immediatament */
/* No cal seguir buscant un cop trobada */
}
}
/* Si el bucle acaba sense haver trobat coincidència */
return -1; /* Retorna -1 per indicar "no trobat" */
/* -1 és un valor convencional perquè no pot ser un índex vàlid */
/* Els índexs vàlids van de 0 a mida-1 */
}
int main(){ /* Funció principal del programa */
/* Declara i inicialitza un array de 5 proteïnes */
struct Proteina proteines[5] = {
{"Insulina", "MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKT", 0},
/* Inicialització completa: nom, seqüència, longitud (0 = per calcular) */
{"Hemoglobina", "MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTTKTYFPHF", 0},
{"Albumina", "DAHKSEVAHRFKDLGEENFKALVLIAFAQYLQQCPFEDHVKLVNEVTEF", 0},
{"Colagen", "GPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPM", 0},
{"Queratina", "MSRRKFVASSSSLNSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS", 0}
};
int num_proteines = 5; /* Nombre total de proteïnes a l'array */
/* Es podria calcular amb sizeof(proteines)/sizeof(proteines[0]) */
/* Calcula la longitud de cada proteïna a partir de la seva seqüència */
printf("=== CALCULANT LONGITUDS ===\n");
for(int i = 0; i < num_proteines; i++){
proteines[i].longitud = strlen(proteines[i].sequencia);
/* strlen() retorna el nombre de caràcters de la cadena (sense comptar '\0') */
printf(" %s: %d aminoacids\n", proteines[i].nom, proteines[i].longitud);
}
/* Demana a l'usuari quina proteïna vol buscar */
char buscar[50]; /* Buffer per al nom a buscar */
printf("\nQuina proteina vols buscar? "); /* Demana el nom */
scanf("%49s", buscar); /* Llegeix fins a 49 caràcters (deixant espai per a '\0') */
/* %49s limita la lectura per evitar desbordaments */
/* Crida a la funció de cerca lineal */
int posicio = cerca_lineal(proteines, num_proteines, buscar);
/* Passa l'array, la mida i el nom a buscar */
/* El resultat s'emmagatzema a 'posicio' */
/* Avalua el resultat de la cerca */
if(posicio != -1){ /* Si s'ha trobat (posicio != -1) */
printf("\n=== PROTEINA TROBADA ===\n");
printf(" Nom: %s\n", proteines[posicio].nom); /* Mostra el nom */
printf(" Sequencia: %s\n", proteines[posicio].sequencia); /* Mostra la seqüència */
printf(" Longitud: %d aminoacids\n", proteines[posicio].longitud); /* Mostra la longitud */
printf(" Index a l'array: %d\n", posicio); /* Mostra la posició */
} else { /* Si no s'ha trobat (posicio == -1) */
printf("\nProteina '%s' no trobada a la base de dades.\n", buscar);
printf("Proteines disponibles:\n");
for(int i = 0; i < num_proteines; i++)
printf(" - %s\n", proteines[i].nom); /* Mostra les proteïnes disponibles */
}
/* Demostració de l'eficiència de la cerca lineal */
printf("\n=== ANALISI DE LA CERCA LINEAL ===\n");
printf("Complexitat temporal: O(n)\n"); /* Notació Big O: creix linealment amb n */
printf(" Millor cas: O(1) - l'element buscat es el primer\n");
printf(" Pitjor cas: O(n) - l'element buscat es l'ultim o no hi es\n");
printf(" Cas mitja: O(n/2) - aproximadament la meitat de l'array\n");
return 0; /* Finalitza el programa amb èxit */
}
Ordena un vector de floats (pH de mostres) amb qsort() de manera ascendent i mostra el resultat.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf() */
#include <stdlib.h> /* Inclou la biblioteca estàndard */
/* Necessària per a qsort() - Quick Sort */
/* qsort() és una funció d'ordenació ràpida incorporada a C */
/* Funció de comparació per a qsort() */
/* Aquesta funció és necessària perquè qsort() sigui genèrica */
/* qsort() necessita saber COM comparar dos elements */
int comparar_floats(const void *a, const void *b){
/* Paràmetres:
- a, b: punters genèrics (void*) als elements a comparar
- const: la funció no modificarà els valors
Retorna:
- valor negatiu si *a < *b (a va abans que b)
- 0 si *a == *b (són iguals)
- valor positiu si *a > *b (a va després que b) */
/* Converteix els punters void* a float* i obté els valors */
float valor_a = *(const float*)a; /* (const float*)a: converteix void* a float* */
/* *(const float*)a: desreferencia per obtenir el float */
float valor_b = *(const float*)b; /* Igual per a b */
/* Compara els valors i retorna el resultat */
if(valor_a < valor_b)
return -1; /* a és menor que b: a va abans (ordre ascendent) */
else if(valor_a > valor_b)
return 1; /* a és major que b: a va després (ordre ascendent) */
else
return 0; /* Són iguals: ordre indiferent */
}
/* Funció alternativa: comparació en ordre descendent */
int comparar_floats_desc(const void *a, const void *b){
float valor_a = *(const float*)a;
float valor_b = *(const float*)b;
/* Inverteix la lògica per obtenir ordre descendent */
if(valor_a > valor_b)
return -1; /* a és major: va abans (ordre descendent) */
else if(valor_a < valor_b)
return 1; /* a és menor: va després (ordre descendent) */
else
return 0;
}
int main(){ /* Funció principal del programa */
/* Array de pH de mostres de laboratori */
float pH_mostres[] = {7.4, 5.2, 8.1, 6.3, 7.0, 4.8, 9.2, 6.8, 7.35, 5.9};
/* Valors típics de pH en mostres biològiques:
- Sang: ~7.4
- Orina: 5.0-8.0
- Saliva: 6.2-7.4
- Suc gàstric: 1.5-3.5 */
/* Calcula el nombre d'elements de l'array */
int n = sizeof(pH_mostres) / sizeof(pH_mostres[0]);
/* sizeof(pH_mostres): mida total de l'array en bytes (10 * 4 = 40 bytes) */
/* sizeof(pH_mostres[0]): mida d'un element (4 bytes per a float) */
/* 40 / 4 = 10 elements */
/* Mostra l'array original (sense ordenar) */
printf("=== MESURES DE pH DE MOSTRES BIOLOGIQUES ===\n\n");
printf("Array original (sense ordenar):\n ");
for(int i = 0; i < n; i++){
printf("%.2f ", pH_mostres[i]); /* Mostra cada valor amb 2 decimals */
}
printf("\n\n");
/* Crida a qsort() per ordenar l'array */
/* Sintaxi: qsort(array, nombre_elements, mida_element, funcio_comparacio) */
qsort(pH_mostres, /* Punter al primer element de l'array */
n, /* Nombre d'elements a ordenar */
sizeof(float), /* Mida en bytes de cada element */
comparar_floats); /* Funció de comparació (punter a funció) */
/* qsort() modifica l'array original in situ */
/* Utilitza l'algorisme Quick Sort: eficiència mitjana O(n log n) */
/* Mostra l'array ordenat ascendentment */
printf("Array ordenat ascendentment (pH de menor a major):\n ");
for(int i = 0; i < n; i++){
printf("%.2f ", pH_mostres[i]);
}
printf("\n");
/* Mostra informació addicional sobre les mostres */
printf("\n=== INFORMACIO ADDICIONAL ===\n");
printf("pH minim: %.2f\n", pH_mostres[0]); /* Després d'ordenar ascendent, el mínim és el primer */
printf("pH maxim: %.2f\n", pH_mostres[n-1]); /* El màxim és l'últim */
printf("pH mitja: %.2f\n", (pH_mostres[0] + pH_mostres[n-1]) / 2); /* Mitjana aritmètica simple */
/* Classificació de les mostres segons el pH */
printf("\n=== CLASSIFICACIO DE LES MOSTRES ===\n");
for(int i = 0; i < n; i++){
printf(" pH %.2f: ", pH_mostres[i]);
if(pH_mostres[i] < 5.5)
printf("ACID (possible suc gastric o fermentacio)\n");
else if(pH_mostres[i] < 6.5)
printf("Lleugerament acid (possible orina)\n");
else if(pH_mostres[i] < 7.5)
printf("NEUTRE (possible sang o saliva)\n");
else if(pH_mostres[i] < 8.5)
printf("Lleugerament basic (possible orina alcalina)\n");
else
printf("BASIC (possible mostra contaminada)\n");
}
/* Demostració de l'ordenació descendent */
printf("\n=== ORDENACIO DESCENDENT (DEMOSTRACIO) ===\n");
qsort(pH_mostres, n, sizeof(float), comparar_floats_desc);
printf("Array ordenat descendentment (pH de major a menor):\n ");
for(int i = 0; i < n; i++){
printf("%.2f ", pH_mostres[i]);
}
printf("\n");
return 0; /* Finalitza el programa amb èxit */
}
Crea una funció de comparació que ordeni proteïnes per longitud de manera descendent i busca la més llarga amb bsearch().
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <stdlib.h> /* Inclou la biblioteca estàndard */
/* Necessària per a qsort() i bsearch() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen() i strcmp() */
/* Definició de l'estructura Proteina */
struct Proteina {
char nom[50]; /* Nom de la proteïna */
char sequencia[200]; /* Seqüència d'aminoàcids */
int longitud; /* Longitud de la seqüència */
};
/* Funció de comparació per ordenar per LONGITUD (ascendent) */
/* Aquesta funció s'usa amb qsort() per ordenar l'array */
int comparar_per_longitud_asc(const void *a, const void *b){
/* Converteix els punters void* a punters a struct Proteina */
const struct Proteina *prot_a = (const struct Proteina*)a;
const struct Proteina *prot_b = (const struct Proteina*)b;
/* (const struct Proteina*): cast de void* al tipus correcte */
/* Compara les longituds de les dues proteïnes */
if(prot_a->longitud < prot_b->longitud)
return -1; /* a és més curta: va abans (ascendent) */
else if(prot_a->longitud > prot_b->longitud)
return 1; /* a és més llarga: va després (ascendent) */
else
return 0; /* Mateixa longitud */
}
/* Funció de comparació per ordenar per LONGITUD (descendent) */
int comparar_per_longitud_desc(const void *a, const void *b){
const struct Proteina *prot_a = (const struct Proteina*)a;
const struct Proteina *prot_b = (const struct Proteina*)b;
/* Inverteix la lògica per obtenir ordre descendent */
if(prot_a->longitud > prot_b->longitud)
return -1; /* a és més llarga: va abans (descendent) */
else if(prot_a->longitud < prot_b->longitud)
return 1; /* a és més curta: va després (descendent) */
else
return 0;
}
/* Funció de comparació per a bsearch() */
/* bsearch() necessita una funció que compari la CLAU amb un ELEMENT */
int comparar_per_bsearch(const void *clau, const void *element){
/* clau: punter al valor buscat (int: longitud buscada) */
/* element: punter a un element de l'array (struct Proteina) */
int longitud_buscada = *(const int*)clau; /* Desreferencia la clau per obtenir l'enter */
const struct Proteina *prot = (const struct Proteina*)element; /* Converteix l'element */
/* Compara la longitud buscada amb la longitud de l'element */
if(longitud_buscada < prot->longitud)
return -1;
else if(longitud_buscada > prot->longitud)
return 1;
else
return 0; /* Longituds iguals: trobat! */
}
int main(){ /* Funció principal */
/* Declara i inicialitza un array de proteïnes */
struct Proteina proteines[] = {
{"Colagen", "GPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPM", 0},
{"Insulina", "MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKT", 0},
{"Queratina", "MSRRKFVASSSSLNSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS", 0},
{"Hemoglobina", "MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTTKTYFPHF", 0},
{"Albumina", "DAHKSEVAHRFKDLGEENFKALVLIAFAQYLQQCPFEDHVKLVNEVTEF", 0},
{"Mioglobina", "MGLSDGEWQLVLNVWGKVEADIPGHGQEVLIRLFKGHPETLEKFDKFKHLKSEDEMKASEDLKKHGATVLTALGGILKKKGHHEAEIKPLAQSHATKHKIPVKYLEFISECIIQVLQSKHPGDFGADAQGAMNKALELFRKDMASNYKELGFQG", 0}
};
int n = sizeof(proteines) / sizeof(proteines[0]); /* Calcula el nombre de proteïnes */
/* Calcula les longituds de totes les proteïnes */
printf("=== PROTEINES I LES SEVES LONGITUDS ===\n");
for(int i = 0; i < n; i++){
proteines[i].longitud = strlen(proteines[i].sequencia);
printf(" %-15s: %3d aminoacids\n", proteines[i].nom, proteines[i].longitud);
}
/* Ordena per longitud descendent (de més llarga a més curta) */
printf("\n=== ORDENACIO PER LONGITUD (DESCENDENT) ===\n");
qsort(proteines, n, sizeof(struct Proteina), comparar_per_longitud_desc);
/* qsort() modifica l'array original */
/* Mostra l'array ordenat */
printf("%-15s %8s %s\n", "PROTEINA", "LONGITUD", "SEQUENCIA (primers 40 aa)");
printf("----------------------------------------------\n");
for(int i = 0; i < n; i++){
printf("%-15s %8d %.40s...\n",
proteines[i].nom,
proteines[i].longitud,
proteines[i].sequencia); /* %.40s: mostra com a màxim 40 caràcters */
}
/* La proteïna més llarga és la primera (després d'ordenar descendent) */
printf("\nProteina mes llarga: %s (%d aminoacids)\n",
proteines[0].nom, proteines[0].longitud);
/* Cerca binària amb bsearch() */
/* REQUISIT: l'array ha d'estar ORDENAT segons el criteri de cerca */
printf("\n=== CERCA BINARIA (bsearch) ===\n");
printf("Nota: bsearch() requereix que l'array estigui ordenat.\n");
/* Busca una proteïna amb longitud 51 (Insulina) */
int longitud_buscar = 51; /* Longitud a buscar */
printf("Buscant proteina amb longitud %d...\n", longitud_buscar);
/* bsearch() retorna un punter a l'element trobat, o NULL si no el troba */
struct Proteina *trobada = (struct Proteina*)bsearch(
&longitud_buscar, /* Punter a la clau de cerca (l'adreça de l'enter) */
proteines, /* Punter a l'array on buscar */
n, /* Nombre d'elements de l'array */
sizeof(struct Proteina),/* Mida de cada element */
comparar_per_bsearch /* Funció de comparació clau-element */
);
if(trobada != NULL){ /* Si bsearch() ha trobat l'element */
printf(" Proteina trobada: %s\n", trobada->nom);
printf(" Longitud: %d aminoacids\n", trobada->longitud);
printf(" Sequencia: %.50s...\n", trobada->sequencia);
} else {
printf(" No s'ha trobat cap proteina amb longitud %d.\n", longitud_buscar);
}
/* Comparativa cerca lineal vs cerca binària */
printf("\n=== COMPARATIVA D'EFICIENCIA ===\n");
printf("Cerca lineal: O(n) - recorre tot l'array\n");
printf("Cerca binaria: O(log n) - divideix l'espai de cerca a cada pas\n");
printf(" Amb %d elements:\n", n);
printf(" Lineal: fins a %d comparacions (pitjor cas)\n", n);
printf(" Binaria: fins a %d comparacions (pitjor cas)\n",
(int)(log2(n) + 1)); /* Nombre màxim de passos en cerca binària */
return 0; /* Finalitza el programa amb èxit */
}
/* Funció auxiliar per calcular log2 (no disponible a math.h en tots els sistemes) */
int log2(int x){
int resultat = 0;
while(x > 1){
x /= 2;
resultat++;
}
return resultat;
}
Escriu un programa que llegeixi proteïnes d'un fitxer, les ordeni segons el criteri triat per l'usuari i guardi el resultat.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf(), scanf(), fopen(), fprintf(), fgets(), fclose() */
#include <stdlib.h> /* Inclou la biblioteca estàndard */
/* Necessària per a malloc(), free(), qsort(), bsearch() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen(), strcpy(), strcmp(), strcat() */
#include <ctype.h> /* Inclou la biblioteca per a classificació de caràcters */
/* Necessària per a toupper() */
/* Definició global del tipus Proteina amb typedef */
/* typedef crea un àlies: 'Proteina' en lloc de 'struct Proteina' */
typedef struct {
char *nom; /* Punter al nom (memòria dinàmica per a flexibilitat) */
char *sequencia; /* Punter a la seqüència (memòria dinàmica) */
int longitud; /* Longitud de la seqüència */
} Proteina; /* Ara 'Proteina' és un tipus vàlid */
/* Variables globals per a la gestió de proteïnes */
Proteina *llista = NULL; /* Array dinàmic de proteïnes (creixerà amb malloc/realloc) */
int total = 0; /* Nombre total de proteïnes carregades */
/* Prototips de les funcions del programa */
int carregar_proteines(const char *nom_fitxer); /* Carrega proteïnes d'un fitxer */
void mostrar_proteines(); /* Mostra la llista per pantalla */
void ordenar_proteines(); /* Menú d'ordenació */
void guardar_proteines(const char *nom_fitxer); /* Guarda la llista en un fitxer */
void cercar_proteina(); /* Cerca binària per nom */
void alliberar_memoria(); /* Allibera tota la memòria */
/* Funcions de comparació per a qsort() */
int comparar_per_nom(const void *a, const void *b); /* Alfabètica ascendent */
int comparar_per_longitud_asc(const void *a, const void *b); /* Longitud ascendent */
int comparar_per_longitud_desc(const void *a, const void *b); /* Longitud descendent */
/* Funció de comparació per a bsearch() (cerca per nom) */
int comparar_per_nom_bsearch(const void *clau, const void *element);
int main(){ /* Funció principal del programa */
char nom_fitxer[100]; /* Nom del fitxer d'entrada */
int opcio; /* Opció del menú */
printf("========================================\n");
printf(" GESTOR DE PROTEINES - ORDENACIO\n");
printf("========================================\n\n");
/* Demana el fitxer de dades */
printf("Nom del fitxer de proteines: ");
scanf("%99s", nom_fitxer);
/* Carrega les proteïnes del fitxer */
int carregades = carregar_proteines(nom_fitxer);
if(carregades == 0){
printf("No s'han pogut carregar proteines. El programa finalitzara.\n");
return 1;
}
printf("S'han carregat %d proteines correctament.\n\n", carregades);
/* Bucle del menú principal */
do{
printf("\n--- MENU PRINCIPAL ---\n");
printf(" 1. Mostrar llista actual\n");
printf(" 2. Ordenar proteines\n");
printf(" 3. Cercar proteina per nom (cerca binaria)\n");
printf(" 4. Guardar llista ordenada\n");
printf(" 0. Sortir\n");
printf(" Opcio: ");
scanf("%d", &opcio);
getchar(); /* Consumeix el '\n' del buffer */
switch(opcio){
case 1:
mostrar_proteines();
break;
case 2:
ordenar_proteines();
break;
case 3:
cercar_proteina();
break;
case 4:
guardar_proteines("proteines_ordenades.txt");
break;
case 0:
printf("\nAlliberant memoria i sortint...\n");
alliberar_memoria();
printf("Adeu!\n");
break;
default:
printf("Opcio no valida.\n");
}
} while(opcio != 0);
return 0; /* Finalitza el programa */
}
/* Funció per carregar proteïnes d'un fitxer */
int carregar_proteines(const char *nom_fitxer){
FILE *fitxer = fopen(nom_fitxer, "r"); /* Obre el fitxer en mode lectura */
if(fitxer == NULL){
printf("Error: No s'ha pogut obrir el fitxer '%s'.\n", nom_fitxer);
printf("Creant fitxer d'exemple 'proteines.txt'...\n");
/* Crea un fitxer d'exemple si no existeix */
fitxer = fopen(nom_fitxer, "w");
if(fitxer == NULL) return 0;
/* Escriu dades d'exemple en format: nom,sequencia */
fprintf(fitxer, "Insulina,MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKT\n");
fprintf(fitxer, "Hemoglobina,MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTTKTYFPHF\n");
fprintf(fitxer, "Albumina,DAHKSEVAHRFKDLGEENFKALVLIAFAQYLQQCPFEDHVKLVNEVTEF\n");
fprintf(fitxer, "Colagen,GPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPM\n");
fprintf(fitxer, "Queratina,MSRRKFVASSSSLNSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n");
fprintf(fitxer, "Mioglobina,MGLSDGEWQLVLNVWGKVEADIPGHGQEVLIRLFKGHPETLEKFDKFKHLKSEDEMKASEDLKKHGATVLTALGGILKKKGHHEAEIKPLAQSHATKHKIPVKYLEFISECIIQVLQSKHPGDFGADAQGAMNKALELFRKDMASNYKELGFQG\n");
fclose(fitxer);
/* Torna a obrir en mode lectura */
fitxer = fopen(nom_fitxer, "r");
if(fitxer == NULL) return 0;
printf("Fitxer d'exemple creat. Si us plau, torna a executar el programa.\n");
fclose(fitxer);
return 0;
}
char linia[1000]; /* Buffer per a cada línia */
/* Bucle de lectura línia per línia */
while(fgets(linia, sizeof(linia), fitxer) != NULL){
/* Elimina el salt de línia */
int len = strlen(linia);
if(len > 0 && linia[len-1] == '\n')
linia[len-1] = '\0';
/* Separa el nom i la seqüència (format: nom,sequencia) */
char *coma = strchr(linia, ','); /* strchr() busca un caràcter en una cadena */
/* Retorna un punter a la primera ocurrència */
if(coma == NULL) continue; /* Si no hi ha coma, ignora la línia */
*coma = '\0'; /* Separa la cadena en dues parts */
char *nom_linia = linia; /* Primera part: nom */
char *seq_linia = coma + 1; /* Segona part: seqüència (després de la coma) */
/* Expandir l'array dinàmic amb realloc() */
Proteina *temp = (Proteina*)realloc(llista, (total + 1) * sizeof(Proteina));
/* realloc() amb NULL es comporta com malloc() */
/* Augmenta l'array en un element cada cop */
if(temp == NULL){
printf("Error de memoria.\n");
break;
}
llista = temp;
/* Reserva memòria per al nom i la seqüència */
llista[total].nom = (char*)malloc((strlen(nom_linia) + 1) * sizeof(char));
llista[total].sequencia = (char*)malloc((strlen(seq_linia) + 1) * sizeof(char));
if(llista[total].nom == NULL || llista[total].sequencia == NULL){
printf("Error de memoria.\n");
break;
}
/* Copia les dades */
strcpy(llista[total].nom, nom_linia);
strcpy(llista[total].sequencia, seq_linia);
llista[total].longitud = strlen(seq_linia); /* Calcula la longitud */
total++; /* Incrementa el comptador */
}
fclose(fitxer);
return total; /* Retorna el nombre de proteïnes carregades */
}
/* Funció per mostrar la llista de proteïnes */
void mostrar_proteines(){
if(total == 0){
printf("\nNo hi ha proteines carregades.\n");
return;
}
printf("\n=== LLISTA DE PROTEINES ===\n");
printf("%-5s %-20s %8s %s\n", "NUM", "NOM", "LONGITUD", "SEQUENCIA (primers 40 aa)");
printf("--------------------------------------------------------------\n");
for(int i = 0; i < total; i++){
printf("%-5d %-20s %8d %.40s%s\n",
i + 1,
llista[i].nom,
llista[i].longitud,
llista[i].sequencia,
llista[i].longitud > 40 ? "..." : "");
}
}
/* Funció per al menú d'ordenació */
void ordenar_proteines(){
if(total == 0){
printf("\nNo hi ha proteines per ordenar.\n");
return;
}
int criteri;
printf("\n--- CRITERIS D'ORDENACIO ---\n");
printf(" 1. Per nom (alfabetic ascendent)\n");
printf(" 2. Per longitud (ascendent: de mes curta a mes llarga)\n");
printf(" 3. Per longitud (descendent: de mes llarga a mes curta)\n");
printf(" Selecciona el criteri: ");
scanf("%d", &criteri);
/* Selecciona la funció de comparació segons el criteri */
int (*funcio_comparacio)(const void*, const void*) = NULL; /* Punter a funció */
/* Un punter a funció emmagatzema l'adreça d'una funció */
/* La sintaxi és complexa: tipus_retorn (*nom)(paràmetres) */
const char *descripcio = ""; /* Descripció de l'ordenació */
switch(criteri){
case 1:
funcio_comparacio = comparar_per_nom;
descripcio = "nom (alfabetic ascendent)";
break;
case 2:
funcio_comparacio = comparar_per_longitud_asc;
descripcio = "longitud (ascendent)";
break;
case 3:
funcio_comparacio = comparar_per_longitud_desc;
descripcio = "longitud (descendent)";
break;
default:
printf("Criteri no valid.\n");
return;
}
/* Executa l'ordenació amb qsort() */
qsort(llista, total, sizeof(Proteina), funcio_comparacio);
printf("\nLlista ordenada per %s:\n", descripcio);
mostrar_proteines();
}
/* Funció per guardar la llista en un fitxer */
void guardar_proteines(const char *nom_fitxer){
if(total == 0){
printf("\nNo hi ha proteines per guardar.\n");
return;
}
FILE *fitxer = fopen(nom_fitxer, "w");
if(fitxer == NULL){
printf("Error: No s'ha pogut crear el fitxer '%s'.\n", nom_fitxer);
return;
}
/* Escriu la capçalera */
fprintf(fitxer, "========================================\n");
fprintf(fitxer, " PROTEINES ORDENADES\n");
fprintf(fitxer, "========================================\n\n");
fprintf(fitxer, "%-5s %-20s %8s %s\n", "NUM", "NOM", "LONGITUD", "SEQUENCIA");
fprintf(fitxer, "--------------------------------------------------------------\n");
/* Escriu cada proteïna */
for(int i = 0; i < total; i++){
fprintf(fitxer, "%-5d %-20s %8d %s\n",
i + 1,
llista[i].nom,
llista[i].longitud,
llista[i].sequencia);
}
fclose(fitxer);
printf("\nFitxer '%s' creat correctament amb %d proteines.\n", nom_fitxer, total);
}
/* Funció per cercar una proteïna amb cerca binària */
void cercar_proteina(){
if(total == 0){
printf("\nNo hi ha proteines per cercar.\n");
return;
}
/* La cerca binària REQUEREIX que l'array estigui ordenat */
/* Primer ordenem per nom alfabèticament */
qsort(llista, total, sizeof(Proteina), comparar_per_nom);
printf("Llista ordenada alfabeticament per a la cerca binaria.\n");
char nom_buscar[100];
printf("\nNom de la proteina a cercar: ");
scanf("%99s", nom_buscar);
/* Cerca binària amb bsearch() */
Proteina *trobada = (Proteina*)bsearch(
nom_buscar, /* Clau: el nom a buscar */
llista, /* Array on buscar */
total, /* Nombre d'elements */
sizeof(Proteina), /* Mida de cada element */
comparar_per_nom_bsearch /* Funció de comparació */
);
if(trobada != NULL){
printf("\n=== PROTEINA TROBADA ===\n");
printf(" Nom: %s\n", trobada->nom);
printf(" Longitud: %d aminoacids\n", trobada->longitud);
printf(" Sequencia: %s\n", trobada->sequencia);
} else {
printf("\nProteina '%s' no trobada.\n", nom_buscar);
printf("Proteines disponibles:\n");
for(int i = 0; i < total; i++)
printf(" - %s\n", llista[i].nom);
}
}
/* Funció per alliberar tota la memòria dinàmica */
void alliberar_memoria(){
for(int i = 0; i < total; i++){
free(llista[i].nom); /* Allibera el nom */
free(llista[i].sequencia); /* Allibera la seqüència */
}
free(llista); /* Allibera l'array de punters */
llista = NULL;
total = 0;
}
/* ============================================ */
/* FUNCIONS DE COMPARACIÓ PER A qsort() */
/* ============================================ */
/* Comparació per nom (alfabètica ascendent) */
int comparar_per_nom(const void *a, const void *b){
const Proteina *p1 = (const Proteina*)a; /* Converteix void* a Proteina* */
const Proteina *p2 = (const Proteina*)b;
return strcmp(p1->nom, p2->nom); /* strcmp() ja retorna -1, 0 o 1 */
}
/* Comparació per longitud ascendent */
int comparar_per_longitud_asc(const void *a, const void *b){
const Proteina *p1 = (const Proteina*)a;
const Proteina *p2 = (const Proteina*)b;
if(p1->longitud < p2->longitud)
return -1;
else if(p1->longitud > p2->longitud)
return 1;
else
return 0;
}
/* Comparació per longitud descendent */
int comparar_per_longitud_desc(const void *a, const void *b){
const Proteina *p1 = (const Proteina*)a;
const Proteina *p2 = (const Proteina*)b;
/* Inverteix la lògica per a ordre descendent */
if(p1->longitud > p2->longitud)
return -1;
else if(p1->longitud < p2->longitud)
return 1;
else
return 0;
}
/* Funció de comparació per a bsearch() (cerca per nom) */
int comparar_per_nom_bsearch(const void *clau, const void *element){
/* clau: punter a la cadena amb el nom buscat */
/* element: punter a un element Proteina de l'array */
const char *nom_buscat = (const char*)clau;
const Proteina *prot = (const Proteina*)element;
return strcmp(nom_buscat, prot->nom); /* Compara les cadenes */
}