Autor
|
Tema: Petición de ayuda para un problema bastante básico de programación en c++ (Leído 3,622 veces)
|
JoaquinVT312
Desconectado
Mensajes: 3
|
Soy nuevo programando, y tengo que entregar un ejercicio y estoy bastante perdido, debo hacer que el programa me diga si una receta de comida es vegetariana o no, viendo si alguno de los ingredientes que contiene es animal, imprimiendo un 1 si lo es, un 0 si no lo es o un -1 si hay algún ingrediente de la receta que no este en la base de datos que da el enunciado. Llevo algo hecho pero estoy muy perdido puesto que soy nuevo y no sé aún como funcionan este tipo de programas. Agradecería algo de ayuda, por favor. Adjunto el programa tal y como lo llevo. #include <stdio.h> #define TAMCAD 100 // Tamaño máximo de cadenas de caracteres #define MAXING 20 // Nro máximo de ingredientes por receta // Definición de estructuras del problema struct propiedades{ float grasas; // gramos de grasa por cada 100gr float hidratos; // gramos de hidratos de carbono por cada 100gr float proteina; // gramos de proteina de carbono por cada 100gr int Kcalorias; // KiloCalorías por 100gr char tipo; // Tipo de alimento: 'V'=Vegetal, 'A'=Animal, 'M'=Mineral, 'L'=Lacteo o huevo }; struct ingredientes{ int id; // Identificador del ingrediente char nombre[TAMCAD]; // Nombre del ingrediente struct propiedades nutrientes; // Propiedades del ingrediente }; struct receta{ char nombre[TAMCAD]; // Nombre de la receta int numIngredientes; // Nro de ingredientes de la receta int id[MAXING]; // Identificador del ingrediente int cantidad[MAXING]; // Gramos del ingrediente a utilizar }; // PROTOTIPO: COMPLETAR float procesaReceta(int ingredientes tipos[], int tiposIngredientes, int receta R[]); int main() { float res; int numTiposIngredientes = 11; // Nro de tipos de ingrediente disponibles // Tabla de ingrediente de ejemplo struct ingredientes tiposIngredientes[]={ {2543,"Aceite de oliva",{99.9, 0, 0, 887,'V'}}, {2361,"Ajo",{0.23,24.3,4,117,'V'}}, {2660,"Arroz",{0.9,86,7,387,'V'}}, {2134,"Atun",{3.3,0,22,119,'A'}}, {2127,"Huevo",{11.1,0,12.5,150,'L'}}, {2403,"Patata",{0.2,15.2,2.2,73,'V'}}, {2419,"Setas",{0.3,4,1.8,26,'V'}}, {2677,"Harina de trigo",{0,71.5,10,333,'V'}}, {866, "Sal",{0,0,0,0,'M'}}, {2493,"Leche de vaca",{3.8,4.7,3,65,'L'}}, {2285,"Pavo",{8.5,0,21,158,'A'}} }; // Algunas recetas de prueba struct receta r[3]={ {"Tortilla",4,{2543,2403,866,2127},{60,300,3,100}}, {"Arroz con setas",5,{2543,2361,2660,2419,866},{40,15,250,125,5}}, {"Pizza",6,{2543,2677,2134,2127,866,0},{20,150,100,80,4,0}} // Esta receta tiene un ingrediente 0 que no existe }; // LLamada a función procesaReceta. Pruebe diferentes recetas anteriores: r[0], r[1] o r[2] res = procesaReceta(ingredientes tipos, tiposIngredientes, receta R[0]); // Resultado printf("El valor resultado es %f\n",res ); } // ======= COPIE EN DOCTUS A PARTIR DE ESTA lÍNEA =========================== // Aquí prototipo de posbles funciones auxiliares que emplee // Definición de su función solución float procesaReceta(int ingredientes tipos[], int tiposIngredientes, int receta R[]) { int i,j,flag; float receta=1; for(i=0;i<(R->numIngredientes) && receta!=-1; i++){ for(j=0; j<tiposIngredientes && receta!=-1; j++){ if(R->id[i]==tipos[j].id){ receta=(tipos[j].nutrientes.tipo=='A'); receta=0; if(R->id[i]!=tipos[j].id){ receta=-1; } } } return receta; }
MOD: El código debe ir entre etiquetas de Código GeSHi
|
|
« Última modificación: 9 Mayo 2021, 12:36 pm por K-YreX »
|
En línea
|
|
|
|
K-YreX
|
El código está bastante bien estructurado (que no es poco decir). Sin embargo, la función procesarReceta() sí que tiene algunos errores: utilizas dos tipos al mismo tiempo (int y struct...).
Antes de empezar con el problema concreto voy a mencionar un par de consejos para utilizarlos yo mismo a partir de aquí: Cuando se define una estructura, puedes utilizar la palabra typedef para crear un nuevo tipo y no tener que utilizar siempre la palabra struct. Los nombres de los structs es mejor que empiecen por mayúscula. typedef struct { char nombre[TAMCAD]; int numIngredientes; int id[MAXING]; int cantidad[MAXING]; } Receta; // Ahora puedes utilizar el tipo Receta asi: Receta miReceta; // en vez de asi: struct Receta miReceta;
En primer lugar, tal y como dices en la explicación, la función debe devolver {1, 0, -1} por lo que el tipo de valor de retorno deberá ser int, mejor que float. Ahora vamos a ver los parámetros... Si tú quieres ver si una receta tiene ingredientes de origen animal necesitarás, para empezar, la receta. ¿Cuántas? 1, la que quieres procesar. No todas las recetas. Por lo que de momento: int procesarReceta(Receta receta, ...);
Ahora esa receta tiene una lista de ingredientes (concretamente un array con los ids de los ingredientes). Entonces necesitarás recibir una lista con todos los ingredientes para poder buscar según su id. Por lo tanto: int procesarReceta(Receta receta, Ingrediente ingredientes[], int numeroIngredientes, ...);
* En C/C++, cuando se pasa un array como parámetro suele ser necesario en la mayoría de los casos pasar un parámetro adicional para saber la longitud de ese array. ** En vez de llamar a la struct "Ingredientes" (en plural), la llamaría "Ingrediente" (en singular). Porque cada instancia será un ingrediente y no varios. A diferencia de "Propiedades" que cada instancia engloba varias propiedades. Y con esos parámetros ya podemos implementar la función, por lo que quedaría así: int procesarReceta(Receta receta, Ingrediente ingredientes[], int numeroIngredientes) { // tu codigo aqui }
Ahora el algoritmo de tu función: Teniendo la receta que quieres comprobar, tienes que recorrer todos sus ingredientes mientras que no hayas encontrado uno que sea animal y mientras no se acaben los ingredientes. Por cada uno de esos ingredientes, debes recorrer el array de ingredientes para encontrar el que coincide según su id y mirar si es de tipo animal. Hay un pequeño detalle que no está bien definido en la explicación: si una receta tiene un ingrediente de origen animal y otro desconocido, qué se debe devolver? 1 o -1? Eso quedará a decisión tuya. En pseudocódigo sería algo así: i := 0 // Indica el indice del ingrediente actual de la receta resultado := 0 // Indica: 0 (no animal) | 1 (animal) | -1 (desconocido) MIENTRAS i < receta.numIngredientes && resultado == 0 HACER j := 0 // Indica el indice del ingrediente actual entre todos los ingredientes MIENTRAS j < numIngredientes && ingredientes[j].id != receta.ingredientes[i] HACER j := j +1 FIN MIENTRAS // Aqui llegamos si hemos encontrado el ingrediente correspondiente segun el id o si no existe SI j < numIngredientes ENTONCES // lo hemos encontrado en la posicion j resultado := (ingredientes[j].tipo == 'A') // Esto sera 1 si la comparacion es true o 0 si es false SINO // no lo hemos encontrado resultado := -1 FIN SI i := i + 1 FIN MIENTRAS RETURN resultado * Este algoritmo devuelve 1 o -1 en función de lo primero que encuentre. Y 0 si no encuentra ninguno de los otros dos casos. Conviértelo a C (es muy sencillo) y pruébalo. A partir de ahí puedes hacer los cambios que consideres.
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
JoaquinVT312
Desconectado
Mensajes: 3
|
El código está bastante bien estructurado (que no es poco decir). Sin embargo, la función procesarReceta() sí que tiene algunos errores: utilizas dos tipos al mismo tiempo (int y struct...).
Antes de empezar con el problema concreto voy a mencionar un par de consejos para utilizarlos yo mismo a partir de aquí: Cuando se define una estructura, puedes utilizar la palabra typedef para crear un nuevo tipo y no tener que utilizar siempre la palabra struct. Los nombres de los structs es mejor que empiecen por mayúscula. typedef struct { char nombre[TAMCAD]; int numIngredientes; int id[MAXING]; int cantidad[MAXING]; } Receta; // Ahora puedes utilizar el tipo Receta asi: Receta miReceta; // en vez de asi: struct Receta miReceta;
En primer lugar, tal y como dices en la explicación, la función debe devolver {1, 0, -1} por lo que el tipo de valor de retorno deberá ser int, mejor que float. Ahora vamos a ver los parámetros... Si tú quieres ver si una receta tiene ingredientes de origen animal necesitarás, para empezar, la receta. ¿Cuántas? 1, la que quieres procesar. No todas las recetas. Por lo que de momento: int procesarReceta(Receta receta, ...);
Ahora esa receta tiene una lista de ingredientes (concretamente un array con los ids de los ingredientes). Entonces necesitarás recibir una lista con todos los ingredientes para poder buscar según su id. Por lo tanto: int procesarReceta(Receta receta, Ingrediente ingredientes[], int numeroIngredientes, ...);
* En C/C++, cuando se pasa un array como parámetro suele ser necesario en la mayoría de los casos pasar un parámetro adicional para saber la longitud de ese array. ** En vez de llamar a la struct "Ingredientes" (en plural), la llamaría "Ingrediente" (en singular). Porque cada instancia será un ingrediente y no varios. A diferencia de "Propiedades" que cada instancia engloba varias propiedades. Y con esos parámetros ya podemos implementar la función, por lo que quedaría así: int procesarReceta(Receta receta, Ingrediente ingredientes[], int numeroIngredientes) { // tu codigo aqui }
Ahora el algoritmo de tu función: Teniendo la receta que quieres comprobar, tienes que recorrer todos sus ingredientes mientras que no hayas encontrado uno que sea animal y mientras no se acaben los ingredientes. Por cada uno de esos ingredientes, debes recorrer el array de ingredientes para encontrar el que coincide según su id y mirar si es de tipo animal. Hay un pequeño detalle que no está bien definido en la explicación: si una receta tiene un ingrediente de origen animal y otro desconocido, qué se debe devolver? 1 o -1? Eso quedará a decisión tuya. En pseudocódigo sería algo así: i := 0 // Indica el indice del ingrediente actual de la receta resultado := 0 // Indica: 0 (no animal) | 1 (animal) | -1 (desconocido) MIENTRAS i < receta.numIngredientes && resultado == 0 HACER j := 0 // Indica el indice del ingrediente actual entre todos los ingredientes MIENTRAS j < numIngredientes && ingredientes[j].id != receta.ingredientes[i] HACER j := j +1 FIN MIENTRAS // Aqui llegamos si hemos encontrado el ingrediente correspondiente segun el id o si no existe SI j < numIngredientes ENTONCES // lo hemos encontrado en la posicion j resultado := (ingredientes[j].tipo == 'A') // Esto sera 1 si la comparacion es true o 0 si es false SINO // no lo hemos encontrado resultado := -1 FIN SI i := i + 1 FIN MIENTRAS RETURN resultado * Este algoritmo devuelve 1 o -1 en función de lo primero que encuentre. Y 0 si no encuentra ninguno de los otros dos casos. Conviértelo a C (es muy sencillo) y pruébalo. A partir de ahí puedes hacer los cambios que consideres. Primero muchas gracias por la atención. Tengo varias dudas al respecto, por si podrías ayudarme, por favor. Primero decir que es verdad que me expliqué mal acerca del ejercicio. El programa devolvería 1 de ser totalmente vegetariana la receta y 0 de encontrar algún alimento animal, pero siempre prevalecería el encontrar un ingrediente desconocido, es decir, de encontrar uno devolvería -1, independientemente ya de que sea vegetal o animal la receta. Segundo decir que es un ejercicio predefinido y, por lo tanto, solo puedo tocar la función, ( no me permite editar el enunciado en sí, y el nombre de las cosas, (lo digo por el tema que me has comentado de facilitar algunas cosas utilizando plurales o no teniendo que usar struct siempre, aún así me ha venido bien y te lo agradezco, puesto que me lo he apuntado para futuros programas en los que si pueda aplicarlos. Tengo dudas sobre la llamada a la función: // LLamada a función procesaReceta. Pruebe diferentes recetas anteriores: r[0], r[1] o r[2] res = procesarReceta(Receta receta, Ingredientes ingredientes[], numIngredientes); Eso me da error y no me deja compilar, por lo que me quedo ahí atascado y no puedo compilar e ir probando s editar el código de la función para ver si va funcionando correctamente o no. Gracias de nuevo por la atención.
|
|
|
En línea
|
|
|
|
K-YreX
|
Primero decir que es verdad que me expliqué mal acerca del ejercicio. El programa devolvería 1 de ser totalmente vegetariana la receta y 0 de encontrar algún alimento animal, pero siempre prevalecería el encontrar un ingrediente desconocido, es decir, de encontrar uno devolvería -1, independientemente ya de que sea vegetal o animal la receta. En el algoritmo anterior he intercambiado el significado del 1 y el 0 pero puedes corregir eso sin mayor problema. También deberás cambiar un poco el código para que busque todos los ingredientes por si alguno es desconocido. Tengo dudas sobre la llamada a la función: // LLamada a función procesaReceta. Pruebe diferentes recetas anteriores: r[0], r[1] o r[2] res = procesarReceta(Receta receta, Ingredientes ingredientes[], numIngredientes); Eso me da error y no me deja compilar, por lo que me quedo ahí atascado y no puedo compilar e ir probando s editar el código de la función para ver si va funcionando correctamente o no. Gracias de nuevo por la atención. Te dará error de compilación porque el prototipo de la función tiene que ser igual que la implementación y no lo habrás cambiado en ambas partes del código. Si el problema no es ese, añade el prototipo de la función, la implementación y la llamada para ver cómo la utilizas.
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
JoaquinVT312
Desconectado
Mensajes: 3
|
En el algoritmo anterior he intercambiado el significado del 1 y el 0 pero puedes corregir eso sin mayor problema. También deberás cambiar un poco el código para que busque todos los ingredientes por si alguno es desconocido. Te dará error de compilación porque el prototipo de la función tiene que ser igual que la implementación y no lo habrás cambiado en ambas partes del código. Si el problema no es ese, añade el prototipo de la función, la implementación y la llamada para ver cómo la utilizas.
Te adjunto lo que llevo porque me sigue saliendo error en la llamada y estoy atascado ahí. De nuevo gracias por la ayuda. #include <stdio.h> #define TAMCAD 100 // Tamaño máximo de cadenas de caracteres #define MAXING 20 // Nro máximo de ingredientes por receta // Definición de estructuras del problema struct propiedades{ float grasas; // gramos de grasa por cada 100gr float hidratos; // gramos de hidratos de carbono por cada 100gr float proteina; // gramos de proteina de carbono por cada 100gr int Kcalorias; // KiloCalorías por 100gr char tipo; // Tipo de alimento: 'V'=Vegetal, 'A'=Animal, 'M'=Mineral, 'L'=Lacteo o huevo }; struct ingredientes{ int id; // Identificador del ingrediente char nombre[TAMCAD]; // Nombre del ingrediente struct propiedades nutrientes; // Propiedades del ingrediente }; struct receta{ char nombre[TAMCAD]; // Nombre de la receta int numIngredientes; // Nro de ingredientes de la receta int id[MAXING]; // Identificador del ingrediente int cantidad[MAXING]; // Gramos del ingrediente a utilizar }; // PROTOTIPO: COMPLETAR int procesarReceta(receta receta, ingredientes ingredientes[], int numIngredientes); int main() { float res; int numTiposIngredientes = 11; // Nro de tipos de ingrediente disponibles // Tabla de ingrediente de ejemplo struct ingredientes tiposIngredientes[]={ {2543,"Aceite de oliva",{99.9, 0, 0, 887,'V'}}, {2361,"Ajo",{0.23,24.3,4,117,'V'}}, {2660,"Arroz",{0.9,86,7,387,'V'}}, {2134,"Atun",{3.3,0,22,119,'A'}}, {2127,"Huevo",{11.1,0,12.5,150,'L'}}, {2403,"Patata",{0.2,15.2,2.2,73,'V'}}, {2419,"Setas",{0.3,4,1.8,26,'V'}}, {2677,"Harina de trigo",{0,71.5,10,333,'V'}}, {866, "Sal",{0,0,0,0,'M'}}, {2493,"Leche de vaca",{3.8,4.7,3,65,'L'}}, {2285,"Pavo",{8.5,0,21,158,'A'}} }; // Algunas recetas de prueba struct receta r[3]={ {"Tortilla",4,{2543,2403,866,2127},{60,300,3,100}}, {"Arroz con setas",5,{2543,2361,2660,2419,866},{40,15,250,125,5}}, {"Pizza",6,{2543,2677,2134,2127,866,0},{20,150,100,80,4,0}} // Esta receta tiene un ingrediente 0 que no existe }; // LLamada a función procesaReceta. Pruebe diferentes recetas anteriores: r[0], r[1] o r[2] res = procesarReceta(receta receta, ingredientes ingredientes[], int numIngredientes); // Resultado printf("El valor resultado es %f\n",res ); } // ======= COPIE EN DOCTUS A PARTIR DE ESTA lÍNEA =========================== // Aquí prototipo de posbles funciones auxiliares que emplee // Definición de su función solución int procesarReceta(receta receta, ingredientes ingredientes[], int numIngredientes) int i:= 0; // Indica el indice del ingrediente actual de la receta int resultado := 0; // Indica: 0 (no animal) | 1 (animal) | -1 (desconocido) while(i < receta.numIngredientes && resultado !=-1) { j := 0; while(j < numIngredientes && ingredientes[j].id != receta.ingredientes[i]) { j := j +1;// Indica el indice del ingrediente actual entre todos los ingredientes } // Aqui llegamos si hemos encontrado el ingrediente correspondiente segun el id o si no existe if (j < numIngredientes){ // lo hemos encontrado en la posicion j if (resultado := (ingredientes[j].tipo == 'A')){ resultado:=0; } }// Esto sera 0 si la comparacion es true o 1 si es false else{// no lo hemos encontrado resultado := -1} i := i + 1; } return resultado; }
MOD: El código debe estar entre etiquetas de Código GeSHi
|
|
« Última modificación: 9 Mayo 2021, 17:33 pm por K-YreX »
|
En línea
|
|
|
|
K-YreX
|
El código publicado en un mensaje debe estar entre etiquetas de Código GeSHi. Puedes seleccionarlas desde el desplegable que dice Código GeSHi (eligiendo el lenguaje adecuado) o escribiendo directamente: [code=c] Tu código aquí [/code]
Tienes 3 problemas: - Al no estar utilizando typedef como indiqué en el primer mensaje, debes utilizar la palabra struct obligatoriamente cada vez que quieras hacer referencia a un struct (struct receta, struct ingredientes,...). Además no utilices el mismo nombre para la struct que para la variable, no es nada recomendable.
- Al momento de utilizar la función (línea 53) no tienes que indicar el tipo sino una variable que se corresponda con ese tipo.
res = procesarReceta(r[0], tiposIngredientes, numTiposIngredientes);
- Te has limitado a copiar casi literalmente mi pseudocódigo (y el pseudocódigo es una forma más o menos flexible de diseñar un algoritmo utilizando sintaxis que no tiene que ser de ningún lenguaje concreto). En C las asignaciones no se hacen con := por lo que esa sintaxis no existe. Además hay un par de líneas que te has medio inventado (79-81) y te he indicado en el comentario anterior que tendrías que hacer ciertos cambios que tampoco veo.
Todos esos errores son muy básicos y cualquier compilador que utilices para compilar tu programa seguro que te indicará la línea del error y el motivo. Si te limitas a copiar la solución sin entenderla, no vas a conseguir nada. El segundo problema demuestra que intentas utilizar una función sin entender su funcionamiento y en general todo demuestra que no quieres entenderlo, sólo conseguir que funcione. Y eso va a ser tu mayor problema. Igual de fácil que me es a mí saber todo eso sólo viendo tu código, le será a tu profesor/a o a quien tengas que entregar ese programa. Y una simple búsqueda por Internet le servirá para ver de dónde has sacado la solución... Intentando engañar a los demás, sólo te engañas a ti mismo.
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Programacion Spricps Linux [peticion]
GNU/Linux
|
Urk83
|
2
|
2,320
|
19 Enero 2012, 22:20 pm
por 2Fac3R
|
|
|
Primeros pasos en programacion, Curso basico para principiantes.
Programación General
|
Elias Peraza
|
0
|
2,177
|
18 Noviembre 2013, 04:56 am
por Elias Peraza
|
|
|
Ayuda con un programa básico (nuevo en programación)
Programación C/C++
|
juanma0311
|
3
|
2,438
|
25 Julio 2014, 10:03 am
por Eternal Idol
|
|
|
Necesito ayuda para realizar un ejercicio bastante complejo en CodeBlocks
Programación C/C++
|
galucas96
|
6
|
3,951
|
28 Noviembre 2014, 13:42 pm
por galucas96
|
|
|
Ayuda con problema básico lenguaje C.
Programación C/C++
|
Shett
|
7
|
3,885
|
15 Noviembre 2016, 19:46 pm
por engel lex
|
|