Acá van mis soluciones para los ejercicios de informática electrónica práctica 3.
Todas las soluciones fueron implementadas usando 4.4.3
AVISO: No me siento exactamente muy alegre con todas las soluciones 😉
Ejercicio 2:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Indice Indice; char ** oraciones; long int cant_oraciones; long int tam_oraciones; char acumulador[256]; void agregarPalabra(char *palabra){ if ( cant_oraciones == tam_oraciones ){ // agrandar Buffer if (tam_oraciones) tam_oraciones = tam_oraciones << 2; // multiplicar por 2 tamaño else tam_oraciones = 1; oraciones = realloc(oraciones, sizeof(char **) * tam_oraciones); }; oraciones[cant_oraciones]=strdup(palabra); cant_oraciones++; } int main(void){ char buffer[1000]; // buffer de lectura char ** puntero; int len = 0; int i = 0; char car; printf("Ingrese texto, presione enter para terminar\n"); printf("Una linéa vacia o EOF se considera fin\n"); while (1){ printf("> "); gets(buffer);//buffer, sizeof(buffer), stdin); // leer entrada len = strlen(buffer); if (len==0 || buffer[0]=='\n'){ printf("FIN\n"); break; } for (i=0; i<len; i++){ car = buffer[i] & 0xff; // limitar a ASCII de 8 bits acumulador[(int)(car&0x00ff)]+=1; } agregarPalabra(buffer); } i = 0; puntero=oraciones; if (!puntero) return 0; while (i < cant_oraciones){ printf("%i: %s\n", i+1, *puntero); i++; puntero++; } for (i=0; i<255; i++){ car = (char) i & 0xff; if (acumulador[i]==0) continue; printf("%c\t%0X:\t%i\n", car, 0xff&car, acumulador[i]); } return 0; }
Ejercicio 3:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> char ** frases=0; int * ocurrencias=0; int cant_frases=0; int espacio_reservado=0; void agregar(const char * frase){ int i; // primero verificar si la conocemos for ( i = 0; i < cant_frases; i++){ if (strcmp(frase, frases[i]) == 0) { ocurrencias[i]+=1; return; } } // ok no la conocemos a agregarla a la lista. if ( i == espacio_reservado){ // crecimiento exponencial del consumo de memoria if (espacio_reservado) espacio_reservado=espacio_reservado<<1; else espacio_reservado=2; printf("realloc para %i elementos\n", espacio_reservado); frases = realloc(frases, sizeof(char*)*espacio_reservado); ocurrencias = realloc(ocurrencias, sizeof(int)*espacio_reservado); } frases[i] = strdup(frase); ocurrencias[i] = 1; cant_frases+=1; } int leerPalabra(char * buffer){ char c; while ( 1 ){ c = getchar(); if ( isspace(c) || ispunct(c) || c==0 ){ *buffer=0; return 0; } if (c==EOF){ *buffer=0; return 1; } *buffer = c; buffer++; } } void ordenar(){ int i, j; char * tempc; int tempi; int test; /* permite saber si esta terminado */ for(i = cant_frases - 1; i > 0; i--) { test=0; for(j = 0; j < i; j++) { if(strcmp(frases[j], frases[j+1]) > 0) /* comparar elementos vecinos */ { tempc = frases[j]; /* intercambiar elementos*/ frases[j] = frases[j+1]; frases[j+1] = tempc; tempi = ocurrencias[j]; /* intercambiar elementos*/ ocurrencias[j] = ocurrencias[j+1]; ocurrencias[j+1] = tempi; test=1; } } /*end for j*/ if(test==0) break; /*will exit if the list is sorted!*/ } /*end for i*/ } int main(void){ char buffer[1000]; // buffer de lectura char c; int len, i; printf("Ingrese palabras, EOF para terminar\n"); while (1){ i = leerPalabra(&buffer); len = strlen(buffer); printf ("%s\n", buffer); if (len > 0){ agregar(buffer); continue; } if (i==1){ printf("FIN\n"); break; } } printf("SIN ORDENAR\n"); for (i=0; i<cant_frases; i++){ printf("%s: %i\n", frases[i], ocurrencias[i]); } printf("\n\n"); printf("ORDENADO\n"); ordenar(); for (i=0; i<cant_frases; i++){ printf("%s: %i\n", frases[i], ocurrencias[i]); } return 0; }
Ejercicio 4:
Similar al 3 pero con estructuras!
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct Frase Frase; struct Frase{ char * frase; int ocurrencias; }; Frase * frases=0; int cant_frases=0; int espacio_reservado=0; void agregar(const char * frase){ int i; // primero verificar si la conocemos for ( i = 0; i < cant_frases; i++){ if (strcmp(frase, frases[i].frase) == 0) { frases[i].ocurrencias+=1; return; } } // ok no la conocemos a agregarla a la lista. if ( i == espacio_reservado){ // crecimiento exponencial del consumo de memoria if (espacio_reservado) espacio_reservado=espacio_reservado<<1; else espacio_reservado=2; printf("realloc para %i elementos\n", espacio_reservado); frases = realloc(frases, sizeof(Frase)*espacio_reservado); } frases[i].frase = strdup(frase); frases[i].ocurrencias = 1; cant_frases+=1; } int leerPalabra(char * buffer){ char c; while ( 1 ){ c = getchar(); if ( isspace(c) || ispunct(c) || c==0 ){ *buffer=0; return 0; } if (c==EOF){ *buffer=0; return 1; } *buffer = c; buffer++; } } void ordenar(){ int i, j; Frase temp; int test; /* permite saber si esta terminado */ for(i = cant_frases - 1; i > 0; i--) { test=0; for(j = 0; j < i; j++) { if(strcmp(frases[j].frase, frases[j+1].frase) > 0) /* comparar elementos vecinos */ { temp = frases[j]; /* intercambiar elementos*/ frases[j] = frases[j+1]; frases[j+1] = temp; test=1; } } /*end for j*/ if(test==0) break; /*will exit if the list is sorted!*/ } /*end for i*/ } int main(void){ char buffer[1000]; // buffer de lectura int len, i; printf("Ingrese palabras, EOF para terminar\n"); while (1){ i = leerPalabra(&buffer); len = strlen(buffer); printf ("%s\n", buffer); if (len > 0){ agregar(buffer); continue; } if (i==1){ printf("FIN\n"); break; } } printf("SIN ORDENAR\n"); for (i=0; i<cant_frases; i++){ printf("%s: %i\n", frases[i].frase, frases[i].ocurrencias); } printf("\n\n"); printf("ORDENADO\n"); ordenar(); for (i=0; i<cant_frases; i++){ printf("%s: %i\n", frases[i].frase, frases[i].ocurrencias); } return 0; }
Ejercicio 5:
Usando lista enlazada, ordenando al momento de cargar, cómo me gusta las estructuras es lo más semejante que conozco a las estructuras de python :D.
Si me preguntan la forma más eficiente de hacerlo, sobre todo con MUCHOS datos!
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct Frase Frase; struct Frase{ char * frase; int ocurrencias; Frase * proxima; }; Frase * inicio=0; void agregar(const char * frase){ int i; Frase * puntero = inicio; Frase * previo = 0; //estupido C no inicializa en 0, sin esto tira verdura! Frase * nueva; printf("agregando %s\n", frase); // primero verificar si la conocemos while ( puntero ){ i = strcmp(frase, puntero->frase); if ( i == 0 ) // la encontramos { printf("conocida sumando\n"); puntero->ocurrencias+=1; return; } else if (i < 0){ // estamos metiendo una nueva frase que es mayor a la última // que estabamos mostrando, entonces podemos insertar de forma // ordenada nueva = malloc(sizeof(Frase)); nueva->frase = strdup(frase); nueva->ocurrencias = 1; nueva->proxima = puntero; if (previo){ previo->proxima = nueva; printf("agreagando entre %s y %s\n", previo->frase, puntero->frase); } else { inicio = nueva; printf("a la cabeza\n"); } return; } previo = puntero; if (puntero->proxima==NULL) break; puntero = puntero->proxima; } // puntero apunta a la última frase // no la conocemos a agregarla a la lista al final. printf("agregando al final\n"); nueva = malloc(sizeof(Frase)); nueva->frase = strdup(frase); nueva->ocurrencias = 1; nueva->proxima = 0; if (puntero){ printf("agregando luego de %s\n", puntero->frase); puntero->proxima = nueva; } if (!inicio){ printf("inicio de la lista\n"); inicio = nueva; } } int leerPalabra(char * buffer){ char c; while ( 1 ){ c = getchar(); if ( isspace(c) || ispunct(c) || c==0 ){ *buffer=0; return 0; } if (c==EOF){ *buffer=0; return 1; } *buffer = c; buffer++; } } int main(void){ char buffer[1000]; // buffer de lectura int len, i; Frase * puntero; printf("Ingrese palabras, EOF para terminar\n"); while (1){ i = leerPalabra(&buffer); len = strlen(buffer); printf ("%s\n", buffer); if (len > 0){ agregar(buffer); continue; } if (i==1){ printf("FIN\n"); break; } } printf("ORDENADA\n"); puntero = inicio; while (puntero){ printf("%s: %i\n", puntero->frase, puntero->ocurrencias); puntero = puntero->proxima; } return 0; }
Ejercicio 6:
Si me preguntan no sé quién escribió un código tan feo, es cómo rascarse la oreja izquierda con la mano derecha, igualmente lo corregí para compilar en GCC.
#include <stdlib.h> #include <stdio.h> void main () { int *vector, *matriz, *resultado; int i,j, nCol, *pi, *pm, *pr; srand48 (time(NULL)); printf("Introduce el numero de columnas del vector/matriz: "); scanf("%d",&nCol); /* Asignamos memoria para vectores y matrices */ vector = malloc(sizeof(int)*nCol); matriz = malloc(sizeof(int)*nCol*nCol); resultado = malloc(sizeof(int)*nCol); if(vector == NULL || matriz == NULL || resultado == NULL){ printf("\nError en la memoria"); return; } printf("\nLa memoria asignada es: "); printf("$\n%10s%10s%10s%10s", "Area","Inicio","Largo","Ultima"); printf("\n%10s%10x%10d%10x", "Vector", vector, sizeof(int)*nCol, vector+nCol); pm=matriz+nCol*nCol; printf("\n%10s%10x%10d%10x", "Matriz", matriz, sizeof(int)*nCol*nCol, pm); pi=resultado; pm=resultado+nCol; printf("\n%10s%10x%10d%10x", "Resultado", pi, pm - resultado, pm); /* "Introduce valores para el vector: "; */ printf("\n\nEl vector es:\n"); /*for (i=0, pi=vector; i<nCol; i++, pi++){*/ for (pi=vector, pm=(vector+nCol); pi<pm; pi++){ *pi = (int) (drand48() * 10); printf("%10d", *pi); } /* "Introduce valores para la fila " */ printf("\n\nLa matriz es:\n"); for (i=0,pi=matriz, pm=(matriz+nCol*nCol); pi<pm; pi++, i++){ *pi = (int) (drand48() * 10);; printf("%10d", *pi); if((i+1)%nCol==0) printf("\n"); } /* Multiplicando */ printf("\n\nOperaciones realizadas:\n"); pi=vector; pm=matriz; pr=resultado; for (i=0; i<nCol; i++, pi++, pr++) { *pr = 0; for ( j=0; j<nCol; j++, pm++) { *pr += *pi * *pm; printf("%5d*%-4d", *pi,*pm); } printf("= %d\n", *pr); } printf("\nEl resultado es: \n"); for (i=0,pi=resultado; i<nCol; i++, pi++) printf("%10d", *pi); printf("\n"); }
Ejercicio 7
Haciendo el acceso a matrices un poco más coherentes.
#include <stdlib.h> #include <stdio.h> int main (void) { int *matriz1, *matriz2, *resultado; int i,j, k, nCol1, nFil1, nCol2, nFil2, *pi, *pm, *pr; srand48 (time(NULL)); printf("Introduce el numero de columnas y filas de la matriz 1 (separadas con espacios): "); scanf("%d %d",&nCol1, &nFil1); printf("Introduce el numero de columnas y filas de la matriz 2 (separadas con espacios): "); scanf("%d %d",&nCol2, &nFil2); if (nCol1 != nFil2){ printf("Tamaños de matrices incompatibles\n"); return 1; } matriz1 = malloc(sizeof(int)*nCol1*nFil1); matriz2 = malloc(sizeof(int)*nCol2*nFil2); resultado = malloc(sizeof(int)*nCol2*nFil1); if(matriz1 == NULL || matriz2 == NULL || resultado == NULL){ printf("\nError en la memoria"); return 1; } printf("\nLa memoria asignada es: "); printf("$\n%10s%10s%10s%10s", "Area","Inicio","Largo","Ultima"); printf("\n%10s%10x%10d%10x", "Matriz1", matriz1, sizeof(int)*nCol1*nFil1, matriz2-1); printf("\n%10s%10x%10d%10x", "Matriz2", matriz2, sizeof(int)*nCol2*nFil2, resultado-1); printf("\n%10s%10x%10d%10x", "Resultado", resultado, sizeof(int)*nFil1*nCol2, resultado+(nCol1*nFil2)); printf("\n\nLa matriz 1 es:\n"); pi=matriz1; for (i=0; i<nFil1; i++){ for (j=0; j<nCol1; j++){ *(pi+i*nCol1+j) = (int) (drand48() * 10); printf("%10d", *(pi+i*nCol1+j)); }; printf("\n"); }; printf("\n\nLa matriz 2 es:\n"); pi=matriz2; for (i=0; i<nFil2; i++){ for (j=0; j<nCol2; j++){ *(pi+i*nCol2+j) = (int) (drand48() * 10); printf("%10d", *(pi+i*nCol2+j)); }; printf("\n"); }; printf("\n\nOperaciones realizadas:\n"); pi=matriz1; pm=matriz2; pr=resultado; for(i=0; i<nFil1; i++){ for(j=0; j<nCol2; j++){ for(k=0; k<nCol1; k++){ *(pr+i*nCol2+j)+=*(pi+i*nCol1+k) * *(pm+k*nCol2+j); printf("%5d*%-4d", *(pi+i*nCol1+k), *(pm+k*nCol2+j)); } printf("= %d\n", *(pr+i*nCol2+j)); } } pi = resultado; printf("\nEl resultado es: \n"); for (i=0; i<nCol2; i++){ for (j=0; j<nFil1; j++){ printf("%10d", *(pi+i*nFil1+j)); } printf("\n"); } printf("\n"); }
Ejercicio 9:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct Articulo Articulo; struct Articulo{ long int id; char * nombre; double precio; long int cantidad; }; Articulo * articulos; long int cantidad_articulos=0; long int capacidad_memoria=0; void agregar(Articulo * art){ int i; for (i=0; i<cantidad_articulos; i++){ if (articulos[i].id==art->id){ printf("ID repetido, no se agrega\n"); return; } } if ( capacidad_memoria == cantidad_articulos ){ if ( ! capacidad_memoria ) capacidad_memoria = 2; else capacidad_memoria = capacidad_memoria << 1; articulos = realloc(articulos, sizeof(Articulo)*capacidad_memoria); } articulos[cantidad_articulos] = *art; cantidad_articulos+=1; } int main(void){ Articulo art, *temp; long int id, cantidad; double precio; char buffer[1000]; int i; printf("Ingrese id, nombre, precio, cantidad. EOF para terminar\n"); while (1){ if (scanf( "%ld %s %lf %ld", &(id), &(buffer), &(precio), &(cantidad) )!=4){ printf("FIN\n"); break; } temp=malloc(sizeof(Articulo)); if (temp==NULL){ printf("Error de memoria\n"); break; } temp->id = id; temp->nombre = strdup(buffer); temp->precio = precio; temp->cantidad = cantidad; agregar(temp); } printf("ID\t\tNombre\t\tPrecio\t\tCantidad\t\tCosto Stock\n"); for (i = 0; i < cantidad_articulos; i++){ *temp = articulos[i]; printf("%li\t\t%s\t\t%.2lf\t\t%li\t\t\t%.2lf\n", temp->id, temp->nombre, temp->precio, temp->cantidad, temp->precio * temp->cantidad); } return 0; }
Ejercicio 9:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct Sensor Sensor; typedef struct Medicion Medicion; struct Medicion{ double valor; Medicion * proxima; Medicion * previa; }; struct Sensor{ char id[3]; Medicion * primera; Medicion * ultima; double prom_50; double prom_25; double prom_5; }; Sensor * sensores; long int cantidad_sensores=0; long int capacidad_memoria=0; Sensor* getSensor(char* id){ int i; for (i=0; i<cantidad_sensores; i++){ if (strcmp(sensores[i].id, id)==0){ return &sensores[i]; } } if ( capacidad_memoria == cantidad_sensores ){ if ( ! capacidad_memoria ) capacidad_memoria = 2; else capacidad_memoria = capacidad_memoria << 1; sensores = realloc(sensores, sizeof(Sensor)*capacidad_memoria); } sensores[cantidad_sensores].id[0]=id[0]; sensores[cantidad_sensores].id[1]=id[1]; sensores[cantidad_sensores].id[2]=id[2]; sensores[cantidad_sensores].primera = NULL; cantidad_sensores+=1; printf("Nuevo ID %s\n", id); return &sensores[cantidad_sensores-1]; } void agregarMedicion(char* id, double value){ int i = 0; Sensor * sensor = getSensor(id); Medicion * puntero = sensor->primera; Medicion * temp; double acu; while ( puntero ) { // ir hasta cola de sensado i++; printf("%.2lf\n", puntero->valor); puntero = puntero->proxima; } printf("Se conocen %d lecturas\n", i); if (i > 49){ printf("Se tienen más de 50 lecturas, sacando: %d\n", 50-i+1); temp = sensor->ultima; for ( i = 0; i < 49; i++ ){ if (temp->previa) // proteger por seg faults temp = temp->previa; else break; } sensor->primera=temp; } temp = malloc(sizeof(Medicion)); temp->valor = value; temp->previa = sensor->ultima; if ( sensor->primera == NULL) sensor->primera = temp; if (sensor->ultima) sensor->ultima->proxima=temp; sensor->ultima = temp; // verificar últimas 5 mediciones acu = 0; for (i = 0, temp=sensor->ultima; i<5; i++){ if (temp) acu+=temp->valor; else break; temp=temp->previa; } sensor->prom_5 = acu/i; // promediar // verificar últimas 25 mediciones acu = 0; for (i = 0, temp=sensor->ultima; i < 25; i++){ if (temp) acu+=temp->valor; else break; temp = temp->previa; } sensor->prom_25 = acu/i; // promediar // verificar últimas 50 mediciones acu = 0; for (i = 0, temp=sensor->ultima; i < 50; i++){ if (temp) acu+=temp->valor; else break; temp = temp->previa; } sensor->prom_50 = acu/i; // promediar printf("Sensor: %s, Promedios: %.2lf %.2lf %.2lf\n", sensor->id, sensor->prom_5, sensor->prom_25, sensor->prom_50); } int main(void){ char id[1000]; double medicion; int i; printf("Ingrese id, medicion\n"); while (1){ scanf("%s %lf", &id, &medicion); if (strlen(id)==0) break; agregarMedicion(id, medicion); id[0]=0; } return 0; }