Soluciones Informática Electrónica Práctica 3

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;
}
Advertisements
This entry was posted in c, facultad. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s