| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
leosan
Registrado: 19 Abr 2012 Mensajes: 730 Ubicación: GRAN CANARIA
| Publicado: 26/09/2012 10:08 am | | | Título: |
| | Cita: | | Ya. Listas enlazadas,doblemente enlazadas y árboles. ¡Es que aún no había llegado! |
Saludos! |
| | Volver arriba | |  | Sorancio

Registrado: 29 May 2009 Mensajes: 1157 Ubicación: España
| Publicado: 26/09/2012 12:27 pm | | | Título: |
| ¡Hola!
No me he olvidado de vosotros, pero es que estaba hasta arriba de trabajo. De vez en cuando os echaba un vistazo no creáis.
No veo que problema puedes tener al usar las estructuras...
| Código: | struct estructura { struct estructura * siguiente; };
struct estructura *a, *b;
a = malloc(sizeof(*a)); b = malloc(sizeof(*b));
a->siguiente = b;
|
_________________ Mi página web (en inglés): |
| | Volver arriba | |  | leosan
Registrado: 19 Abr 2012 Mensajes: 730 Ubicación: GRAN CANARIA
| Publicado: 26/09/2012 1:30 pm | | | Título: |
| | Cita: | | UUUPPPSSS !!!, anodadado me has dejado. Mañana probaré.Gracias. |
|
| | Volver arriba | |  | | Anon
Registrado: 07 Mar 2013 Mensajes: 15
| Publicado: 07/03/2013 12:21 pm | | | Título: Ejercicios de Programación |
| Aquí va mi aportación:
Soluciones propuestas
A
2. Se dice que un año es bisiesto cuando es divisible por 4 pero no es divisible por 100. Sabemos que los extraterrestres llegaron a la Tierra en 1491 en forma de humano con apellido de órgano.
¿Cuantos años bisiestos hay entre 1491 y 2012, el fin del mundo?
| Código: | /* Se dice que un año es bisiesto cuando es divisible por 4 pero no es divisible por 100. * Sabemos que los extraterrestres llegaron a la Tierra en 1491 en forma de humano con apellido de órgano. * * ¿Cuántos años bisiestos hay entre 1491 y 2012, el fin del mundo? */
#include <stdio.h>
int main() { int i, j=0; for (i=1491; i<=2012; i++) { if ((i%4==0)&&(i%100!=0)||(i%400==0)) j++; } printf ("Los años bisiestos entre 1491 y 2012 son %i.\nCerrando programa . . .\n", j); return 0; }
|
3. Una pera pesa alrededor de 150g. Tenemos un fichero en que cada línea tiene una número N entre 0 y 1000.
Para cada cantidad de peras tienes que calcular cuantos kilos (séase 1Kg = 1000g) pesaría la cesta.
| Código: | /* Una pera pesa alrededor de 150g. Introduce un número N entre 0 y 1000, que será el número de líneas que leerá el programa. * * Calcular cuantos kilos (séase 1Kg = 1000g) pesaría la cesta. */
#include <stdio.h>
int main() { int n, i, num_peras; printf ("Introduce el número de líneas que vas a introducir:\n"); scanf ("%i", &n); for (i=0; i<n; i++) { printf ("Introduce número de peras: "); scanf ("%i", &num_peras); printf ("La cesta pesaría %f kg.\n", 0.150*num_peras); } printf ("Cerrando programa . . .\n"); return 0; }
|
Es correcto, ¿verdad?
Saludos. |
| | Volver arriba | |  | Masakre
Registrado: 06 Jun 2012 Mensajes: 245
| Publicado: 18/03/2013 2:50 pm | | | Título: Re: Ejercicios de Programación |
| | Sorancio escribió: | 2. Tenemos un fichero CSV y usamos de separador de columnas la coma y de filas el salto de línea. Mediante un fichero de entrada que tendrá K líneas y cada línea tendrá una cantidad de números variable.
Encuentra de cada fila el mayor y el menor número, y luego del conjunto global procesando sólo una vez el fichero. |
Bueno, acá cito mi avance 
| Código: | /* Tenemos un fichero CSV y usamos de separador de columnas el (;) y de filas el salto de línea. Mediante un fichero de entrada que tendrá K líneas y cada línea tendrá una cantidad de números variable, encuentre de cada fila el mayor y el menor número, y luego del conjunto global (procesando sólo una vez el fichero). */
#include <iostream> #include <fstream> #include <string> #include <vector> #include <algorithm> // Para uso de count() #include <cstdlib> // Para uso de atoi() using namespace std;
// Prototipos. void procesar(string, unsigned);
// Vector global. vector <int> mayor; // mayor[k]: mayor elemento de la fila k. vector <int> menor; // menor[k]: menor elemento de la fila k.
int main() { string linea; unsigned K = 0; ifstream archivoE("fichero.csv");
// Evaluamos que se haya abierto correctamente ! if(!archivoE.is_open()){ cout<<"Error al intentar abrir fichero.csv !"<<endl <<"Verifique la existencia del archivo y vuelva a iniciar el programa."; return 1; }
// Procesamos la info, línea tras línea. while(archivoE.good()){ // Método más general que eof() getline(archivoE, linea); procesar(linea, K); ++K; } archivoE.close(); // Cerramos el archivo CSV.
// Encontramos mayor y menor global. int mayorG=mayor[0], menorG=menor[0]; for(size_t i=0; i<K; ++i) { if(mayor[i]>mayorG) mayorG=mayor[i]; if(menor[i]<menorG) menorG=menor[i]; }
cout<<"El mayor global es "<<mayorG<<" y el menor global es "<<menorG<<"."; return 0; }
void procesar(string linea, unsigned K) { vector <int> elementos; size_t i=0; string s;
// Almacenamos todos los elementos de la fila K. while(i<linea.size()) { if(linea[i]==';') { elementos.push_back(atoi(s.c_str())); s.clear(); } else if( isdigit(linea[i]) ) s += linea[i]; ++i; }
// Buscamos el mayor y menor de la fila. mayor[K] = elementos[0]; menor[K] = elementos[0]; for(i=0; i<linea.size(); ++i) if(elementos[i] > mayor[K]) mayor[K] = elementos[i]; else if (elementos[i] < menor[K]) menor[K] = elementos[i]; if(mayor[K]==menor[K]) cout<<"No existe ni mayor ni menor."; else { if(count(elementos.begin(), elementos.end(), mayor[K])>1) cout<<"No existe mayor, "; else cout<<"Mayor: "<<mayor[K]<<", "; if(count(elementos.begin(), elementos.end(), menor[K])>1) cout<<"No existe menor."; else cout<<"Menor: "<<menor[K]<<"."; } } |
Al ejecutar me muestra "ProcesarCSV.exe dejó de funcionar". Cuando uso la herramienta "Debug / Continue" (nunca antes lo hice), ejecuta el programa y se cierra, pero deja marcada la línea siguiente:
| Código: | mayor[K] = elementos[0]; |
Y además aparece lo siguiente en un cuadro:
| Código: | #0 00401867 procesar(linea={static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x3e292c "1;2;3;5;6 "}}, K=0) (E:\Developer Zone\Aplicaciones de escritorio\Proyectos C++\C++ en CodeBlocks\Ejercicios\Ficheros\ProcesarCSV\main.cpp:71) #1 0040145A main() (E:\Developer Zone\Aplicaciones de escritorio\Proyectos C++\C++ en CodeBlocks\Ejercicios\Ficheros\ProcesarCSV\main.cpp:36) |
Estaría muy agradecido de que me ayuden a encontrar una solución a el problema.
Está en modo -Wall (Sorancio le decía modo pedántico y sangriento), pero ni así muestra errores, ni warnings. El error ocurre al momento de la ejecución. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 7516 Ubicación: Mexico
| Publicado: 18/03/2013 9:14 pm | | | Título: |
| La primera vez que se llama a esta función:
| Código: | procesar(linea, K); // K == 0 |
Las sentencias:
| Código: | // Buscamos el mayor y menor de la fila. mayor[K] = elementos[0]; menor[K] = elementos[0]; |
Tratan de acceder al primer elemento de los vectores "mayor" y "menor", el problema es que los vectores inician sin elementos.
Un saludo _________________ C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language |
| | Volver arriba | |  | | Masakre
Registrado: 06 Jun 2012 Mensajes: 245
| Publicado: 18/03/2013 10:07 pm | | | Título: |
| Muchas gracias rir3760.
Ahora sí conseguí que funcionara.
Entrada:
| Código: | 1;2;3;5;6 4;2;3 2;2;3 1;1;1 2;3;4;4;2 |
Salida:
| Código: | Mayor: 6, Menor: 1. Mayor: 4, Menor: 2. Mayor: 3, No existe menor. No existe ni mayor ni menor. No existe mayor, No existe menor. El mayor global es 6 y el menor global es 1. Process returned 0 (0x0) execution time : 0.032 s Press any key to continue. |
Código:
| Código: | /* Tenemos un fichero CSV y usamos de separador de columnas el (;) y de filas el salto de línea. Mediante un fichero de entrada que tendrá K líneas y cada línea tendrá una cantidad de números variable, encuentre de cada fila el mayor y el menor número, y luego del conjunto global (procesando sólo una vez el fichero). */
#include <iostream> #include <fstream> #include <string> #include <vector> #include <algorithm> // Para uso de count() #include <cstdlib> // Para uso de atoi() using namespace std;
// Prototipos. void procesar(string, unsigned);
// Vector global. vector <int> mayor; // mayor[k]: mayor elemento de la fila k. vector <int> menor; // menor[k]: menor elemento de la fila k.
int main() { string linea; unsigned K = 0; ifstream archivoE("fichero.csv");
// Evaluamos que se haya abierto correctamente ! if(!archivoE.is_open()){ cout<<"Error al intentar abrir fichero.csv !"<<endl <<"Verifique la existencia del archivo y vuelva a iniciar el programa."; return 1; }
// Procesamos la info, línea tras línea. while(archivoE.good()){ // Método más general que eof() getline(archivoE, linea); procesar(linea, K); ++K; } archivoE.close(); // Cerramos el archivo CSV.
// Encontramos mayor y menor global. int mayorG=mayor[0], menorG=menor[0]; for(size_t i=0; i<K; ++i) { if(mayor[i]>mayorG) mayorG=mayor[i]; if(menor[i]<menorG) menorG=menor[i]; }
cout<<"El mayor global es "<<mayorG<<" y el menor global es "<<menorG<<"."; return 0; }
void procesar(string linea, unsigned K) { vector <int> elementos; size_t i=0; string s;
// Almacenamos todos los elementos de la fila K. while(i<linea.size()) { if(linea[i]==';') // Al detectar un ';' carga lo previamente leido. { elementos.push_back(atoi(s.c_str())); s.clear(); } else if( isdigit(linea[i]) ) s += linea[i]; ++i; } if(s.size()!=0) // Por si la fila no acaba en ';' elementos.push_back(atoi(s.c_str()));
// Buscamos el mayor y menor de la fila. mayor.push_back(elementos[0]); menor.push_back(elementos[0]); for(i=0; i<elementos.size(); ++i) if(elementos[i] > mayor[K]) mayor[K] = elementos[i]; else if (elementos[i] < menor[K]) menor[K] = elementos[i];
// Mostramos los datos de una forma peculiar. if(mayor[K]==menor[K]) cout<<"No existe ni mayor ni menor."; else { if(count(elementos.begin(), elementos.end(), mayor[K])>1) cout<<"No existe mayor, "; else cout<<"Mayor: "<<mayor[K]<<", "; if(count(elementos.begin(), elementos.end(), menor[K])>1) cout<<"No existe menor."; else cout<<"Menor: "<<menor[K]<<"."; } cout<<endl; /* // Muestra datos de cada fila. cout<<"Size: "<<linea.size()<<endl; for(i=0; i<elementos.size(); ++i) cout<<elementos[i]<<";"; cout<<endl<<endl; */ } |
|
| | Volver arriba | |  | Masakre
Registrado: 06 Jun 2012 Mensajes: 245
| Publicado: 22/03/2013 1:44 pm | | | Título: Re: Ejercicios de Programación |
| | Sorancio escribió: | 1. Tenemos un fichero cuyo contenido son K líneas. Cada línea tiene una ecuación de la forma ax + by = c.
Encuentra todas las soluciones al sistema de K ecuaciones. |
A continuación el avance que llevo del ejercicio:
| Código: | /* Tenemos un fichero cuyo contenido son K líneas. Cada línea se corresponde con una ecuación de dos variables: X e Y. Encontrar las posibles soluciones del sistema de K ecuaciones. */
#include <iostream> #include <fstream> #include <vector> #include <cstdlib> // To use atoi() using namespace std;
// Definimos Ecuacion como una estructura. struct Ecuacion { int coefX; int coefY; int cte; }; vector <Ecuacion> Eq;
// Prototipos. void SimplifyEq(Ecuacion); unsigned procesarLinea(string, unsigned);
// Razones de fin instantáneo. string razon[] = { "Se encontraron ecuaciones sin signos de igualdad.", "Existen ecuaciones que no tienen valores despues del signo igual.", "Se encontraron variables sin coeficiente.\nRecuerde escribir 1x en vez de solo x, análogamente con y.", "Se encontro algun caracter extrano.\nSolo se permiten numeros enteros, y los simbolos \'=\', \'+\' y \'-\' ..." };
int main() { ifstream FlujoE("ecuaciones.txt");
// ¿Existe el archivo? if(!FlujoE.is_open()) { cout<<"El archivo \'ecuaciones.txt\' no se ha podido cargar." "\nAsegurese de su existencia, y vuelva a iniciar el programa."<<endl; return 1; }
// ¿Sí? Entonces lo procesamos. string linea; int K = 0, flag; while(FlujoE.good()) // Método más general que eof() { getline(FlujoE, linea); if( (flag=procesarLinea(linea, K)) != 0) // Si ocurrió algo inesperado. Mostrar razón y finalizar. { cout<<razon[flag-1]; return 0; } ++K; } return 0; }
void SimplifyEq(Ecuacion* Pointer) { // Encontramos el menor. int menor = Pointer->coefX; if(Pointer->coefY < menor) menor = Pointer->coefY; if(Pointer->cte < menor) menor = Pointer->cte;
// Usamos la variable menor como centinela. menor = menor/2; // Para evitar tanto proceso. while(menor>0) { if(Pointer->coefX%menor==0 && Pointer->coefY%menor==0 && Pointer->cte%menor==0) { Pointer->coefX /= menor; Pointer->coefY /= menor; Pointer->cte /= menor; } --menor; } }
unsigned procesarLinea(string linea, unsigned K) { Ecuacion EqTemp = {0,0,0}; /* Las Eq pueden ser: 3x+4y=7 2x-6=0 1y+2=0 2y=6x+3 1x=-3y+1 */
// Suprimimos todos los vacíos. while( linea.find(' ') != string::npos ) linea.erase( linea.find(' ') );
if( linea.find('=') == string::npos ) return 1; // Falta signo de igualdad en la Eq. else if ( linea.find('=') == linea.size()-1 ) return 2; // No hay nada después del igual.
if( linea.find('x') == 0 || linea.find('y') == 0 ) return 3; // Variables sin coeficiente antepuesto.
for(size_t i=0; i<linea.size(); ++i) { if( !isdigit(linea[i]) && linea[i]!='=' && linea[i]!='+' && linea[i]!='-' && linea[i]!='x' && linea[i]!='y') return 4; // No es un número, ni símbolo aritmético. }
// Encontramos el coeficiente de x: size_t pos = linea.find('x'); string s; while( pos != string::npos ) // Si se encontró alguna x, { // obtenemos su coeficiente y borramos su rastro. --pos; // Retrocedemos una pos antes de 'x'. while(pos>=0 || isdigit(linea[pos]) || linea[pos]=='+' || linea[pos]=='-') s += linea[pos--]; if( linea.find('x') < linea.find('=') ) EqTemp.coefX += atoi(s.c_str()); else EqTemp.coefX -= atoi(s.c_str());
linea.erase(pos+1, linea.find('x')-pos); pos = linea.find('x'); } cout<<"Coeficiente X de la ecuacion "<<K<<" :"<<EqTemp.coefX; return 0; } |
Aunque está incompleto, antes de seguir escribiendo código decidí probar si funcionaba momentáneamente. Así como está debería encontrar el coeficiente X de las ecuaciones que aparezcan en el archivo ecuaciones.txt, pero el programa finaliza de manera inesperada. Usando el debugger me resalta la línea 116:
| Código: | s += linea[pos--]; |
Gracias de antemano. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 7516 Ubicación: Mexico
| Publicado: 22/03/2013 8:41 pm | | | Título: |
| La parte importante es:
| Código: | // Encontramos el coeficiente de x: size_t pos = linea.find('x');
// ...
while (pos>=0 || isdigit(linea[pos]) || linea[pos]=='+' || linea[pos]=='-') s += linea[pos--]; |
Al utilizar el operador logico OR la condicion sera verdadera si cualquiera de las expresiones que la componen es verdadera:
| Código: | pos >= 0 isdigit(linea[pos]) linea[pos] == '+' linea[pos] == '-' |
¿El problema? La variable pos es de tipo size_t y este es un tipo entero sin signo, nunca tomara un valor negativo (al decrementarla pasa de cero a su valor maximo).
Un saludo _________________ C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language |
| | Volver arriba | |  | | Masakre
Registrado: 06 Jun 2012 Mensajes: 245
| Publicado: 23/03/2013 8:43 am | | | Título: |
| Gracias por la ayuda.
Ahora ha quedado así:
| Código: | /* Tenemos un fichero cuyo contenido son K líneas. Cada línea se corresponde con una ecuación de dos variables: X e Y. Encontrar las posibles soluciones del sistema de K ecuaciones. */
#include <iostream> #include <fstream> #include <vector> #include <cstdlib> // To use atoi() #include <algorithm> // To use count() using namespace std;
// Definimos Ecuacion como una estructura. struct Ecuacion { int coefX; int coefY; int cte; }; vector <Ecuacion> Eq;
// Prototipos. void SimplifyEq(Ecuacion); unsigned procesarLinea(string, unsigned);
// Razones de fin instantáneo. string razon[] = { "Se encontraron ecuaciones sin signos de igualdad.", "Existen ecuaciones que no tienen valores despues del signo igual.", "Se encontraron variables sin coeficiente.\nRecuerde escribir 1x en vez de solo x, análogamente con y.", "Se encontro algun caracter extrano.\nSolo se permiten numeros enteros, y los simbolos \'=\', \'+\' y \'-\' ...", "Una de las ecuaciones presenta terminos X adheridos, sin algun signo de intermediario. Por ejemplo: c = axbx." };
int main() { ifstream FlujoE("ecuaciones.txt");
// ¿Existe el archivo? if(!FlujoE.is_open()) { cout<<"El archivo \'ecuaciones.txt\' no se ha podido cargar." "\nAsegurese de su existencia, y vuelva a iniciar el programa."<<endl; return 1; }
// ¿Sí? Entonces lo procesamos. string linea; int K = 0, flag; while(FlujoE.good()) // Método más general que eof() { getline(FlujoE, linea); if( (flag=procesarLinea(linea, K)) != 0) // Si ocurrió algo inesperado. Mostrar razón y finalizar. { cout<<razon[flag-1]; return 0; } ++K; } return 0; }
void SimplifyEq(Ecuacion* Pointer) { // Encontramos el menor. int menor = Pointer->coefX; if(Pointer->coefY < menor) menor = Pointer->coefY; if(Pointer->cte < menor) menor = Pointer->cte;
// Usamos la variable menor como centinela. menor = menor/2; // Para evitar tanto proceso. while(menor>0) { if(Pointer->coefX%menor==0 && Pointer->coefY%menor==0 && Pointer->cte%menor==0) { Pointer->coefX /= menor; Pointer->coefY /= menor; Pointer->cte /= menor; } --menor; } }
unsigned procesarLinea(string linea, unsigned K) { Ecuacion EqTemp = {0,0,0}; /* Las Eq pueden ser: 3x+4y=7 2x-6=0 1y+2=0 2y=6x+3 1x=-3y+1 */
// Suprimimos todos los vacíos. while( linea.find(' ') != string::npos ) linea.erase( linea.find(' ') );
if( linea.find('=') == string::npos ) return 1; // Falta signo de igualdad en la Eq. else if ( linea.find('=') == linea.size()-1 ) return 2; // No hay nada después del igual.
if( linea.find('x') == 0 || linea.find('y') == 0 ) return 3; // Variables sin coeficiente antepuesto.
for(size_t i=0; i<linea.size(); ++i) { if( !isdigit(linea[i]) && linea[i]!='=' && linea[i]!='+' && linea[i]!='-' && linea[i]!='x' && linea[i]!='y') return 4; // No es un número, ni símbolo aritmético. } /* // Ec que continienen algo como "2x3x". string STRtempo = linea; for(size_t i=0; i<STRtempo.size(); ++i) if( isdigit(STRtempo[i]) ) STRtempo.erase(i--); const size_t SZtempo = count(STRtempo.begin(), STRtempo.end(), 'x'); size_t posicionesX[SZtempo]; size_t SZ = SZtempo; for(size_t i=STRtempo.size(); i>=0; --i) if(STRtempo[i] == 'x') { posicionesX[SZ-1] = i; SZ--; } bool es_correcto = false; for(size_t i=0; i<SZ-1; ++i) // No es necesario evaluar la última. for(size_t j=i+1; j<SZ; ++i) for(size_t z=posicionesX[i]+1; z<posicionesX[j]-1; ++z) if(STRtempo[z]=='+'||STRtempo[z]=='-'||STRtempo[z]=='=') { es_correcto = true; goto fin_evaluacion; } fin_evaluacion: if(!es_correcto) return 5; */ // Encontramos el coeficiente de x: short pos = linea.find('x'); string s; while( pos != string::npos ) // Si se encontró alguna x, { // obtenemos su coeficiente y borramos su rastro. --pos; // Retrocedemos una pos antes de 'x'. while(pos>=0) { if( isdigit(linea[pos]) ) s.insert(s.begin(), linea[pos--]); else if(linea[pos]=='+' || linea[pos]=='-') { s.insert(s.begin(), linea[pos--]); break; } else if(linea[pos]=='=') break; }
cout<<"String de algun coefX de "<<K<<": "<<s<<endl; if( linea.find('x') < linea.find('=') ) EqTemp.coefX += atoi(s.c_str()); else EqTemp.coefX -= atoi(s.c_str());
linea.erase(pos+1, linea.find('x')-pos); cout<<"Ecuacion recortada: "<<linea<<endl; pos = linea.find('x'); s.clear(); } cout<<"Coeficiente X de la ecuacion "<<K<<": "<<EqTemp.coefX<<endl<<endl; return 0; } |
Ya no tiene problemas de encontrar el coeficiente de X en cada ecuación. Incluso si se ingresa 3+4+2x=3x-2x el coeficiente de x será admitido como 1. Esto es porque a toda ecuación que ingresa trato de darle la forma Ax+By+C=0.
Sin embargo, si ingreso 4x3x+5=5x6x lo va a considerar como 4x+3x+5=5x+6x. Entonces, hice un intento por determinar ese error en la entrada y advertirle al usuario.
Exactamente se refleja en esta parte que aparece /* toda comentada */ en el programa:
| Código: | // Ec que continienen algo como "2x3x". string STRtempo = linea; for(size_t i=0; i<STRtempo.size(); ++i) if( isdigit(STRtempo[i]) ) STRtempo.erase(i--); const size_t SZtempo = count(STRtempo.begin(), STRtempo.end(), 'x'); size_t posicionesX[SZtempo]; size_t SZ = SZtempo; for(size_t i=STRtempo.size(); i>=0; --i) if(STRtempo[i] == 'x') { posicionesX[SZ-1] = i; SZ--; } bool es_correcto = false; for(size_t i=0; i<SZ-1; ++i) // No es necesario evaluar la última. for(size_t j=i+1; j<SZ; ++i) for(size_t z=posicionesX[i]+1; z<posicionesX[j]-1; ++z) if(STRtempo[z]=='+'||STRtempo[z]=='-'||STRtempo[z]=='=') { es_correcto = true; goto fin_evaluacion; } fin_evaluacion: if(!es_correcto) return 5; |
El problema es que no sé si estoy haciendo instrucciones "ilegales". La idea que he seguido es esta: - Una ecuación que está almacenada como string se almacena en otro string temporal. - A dicho string temporal se le desaparecen los números, quedando por ejemplo: x+=x+ o -x+x=-y - Luego declaro una constante y le asigno el valor devuelto por count(). Donde count() cuenta todas las x en el nuevo string temporal. - Como la variable que declaré es constante la puedo usar para declarar un array de elementos size_t, donde almacenare todas las posiciones de x. - Luego usé la constante declarada y le asigne ese valor a una variable size_t (quise usar cons_cast<size_t>() pero me dijo que sólo es con punteros...). - Aparen 3 fors anidados porque: los 2 primeros toman las posiciones de x almacenadas en el array posicionesX[]. Por ejemplo toma las posiciones 4 y 6, entonces el último for analiza las posiciones que están entre 4 y 6, es decir, sólo la posición 5 del string temporal sin números. - Esas posiciones evaluadas deben contener al menos un caracter de los siguientes: '+', '-' o '='. Si no es así, quiere decir que hay alguna expresión de la forma "axbx" en la ecuación.
Es la primera vez que uso goto creyendo que es lo más conveniente. Gracias nuevamente. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 7516 Ubicación: Mexico
| Publicado: 25/03/2013 9:49 am | | | Título: |
| | Masakre escribió: | | El problema es que no sé si estoy haciendo instrucciones "ilegales". |
Me temo que si.
En C++ estándar no puedes declarar un array de esta forma:
| Código: | const size_t SZtempo = count(STRtempo.begin(), STRtempo.end(), 'x'); size_t posicionesX[SZtempo]; |
Debes revisar si tu compilador soporta esa característica como una extensión o bien utilizar un vector.
Otro error, similar al que ya te había mencionado en el tema:
| Código: | for(size_t i=STRtempo.size(); i>=0; --i) if(STRtempo[i] == 'x'){ posicionesX[SZ-1] = i; SZ--; } |
Las variables sin signo son siempre igual o mayor que cero lo que resulta en un bucle infinito.
Un saludo _________________ C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language |
| | Volver arriba | |  | Masakre
Registrado: 06 Jun 2012 Mensajes: 245
| Publicado: 25/03/2013 12:03 pm | | | Título: |
| | rir3760 escribió: | En C++ estándar no puedes declarar un array de esta forma:
| Código: | const size_t SZtempo = count(STRtempo.begin(), STRtempo.end(), 'x'); size_t posicionesX[SZtempo]; |
Debes revisar si tu compilador soporta esa característica como una extensión o bien utilizar un vector. |
¿Sería de esta otra forma?
| Código: | size_t SZ = count(STRtempo.begin(), STRtempo.end(), 'x'); vector <size_t> posicionesX (SZ, 0); |
Para encontrar formas como "AxBx" mi idea era: - Guardar las posiciones de todas las x en posicionesX[]. - Luego recorrer las posiciones entre posicionesX[i] y posicionesX[i+1]. - En ese recorrido deberían de haberse registrado signos como '+', '-' o '='. - Si en algún tramo no se encontraron esos signos había una forma "AxBx".
Pero ciertamente pudo hacerse así desde un inicio: - Eliminar todos los números. - Recorrer el string de la ecuación. - Si una posición del string era 'x' y estaba seguida de otra 'x', presentaba la forma "AxBx".
Me estaba complicando demasiado para algo tan simple 
Gracias nuevamente. Y... es muy extraño no ver la participación de leosan ! |
| | Volver arriba | |  | | Masakre
Registrado: 06 Jun 2012 Mensajes: 245
| Publicado: 28/03/2013 7:23 am | | | Título: |
| Y esta es mi solución para el ejercicio C1.
| Código: | /* Tenemos un fichero cuyo contenido son K líneas. Cada línea se corresponde con una ecuación de dos variables: X e Y. Encontrar las posibles soluciones del sistema de K ecuaciones. */
#include <iostream> #include <fstream> #include <vector> #include <cstdlib> // To use atoi() #include <algorithm> // To use count() using namespace std;
// Definimos Ecuacion como una estructura. struct Ecuacion { int coefX; int coefY; int cte; }; vector <Ecuacion> Eq;
// Prototipos. void SimplifyEq(Ecuacion*); unsigned procesarLinea(string, unsigned); void printEq(Ecuacion); bool EcEquivalentes(Ecuacion, Ecuacion);
// Razones de fin instantáneo. string razon[] = { "Se encontraron ecuaciones sin signos de igualdad.", "Existen ecuaciones que no tienen valores despues del signo igual.", "Se encontraron variables sin coeficiente.\nRecuerde escribir 1x en vez de solo x, analogamente con y.", "Se encontro algun caracter extrano.\nSolo se permiten numeros enteros, y los simbolos \'=\', \'+\' y \'-\' ...", "Una de las ecuaciones presenta terminos X adheridos, sin algun signo de intermediario. Por ejemplo: c = axbx." };
int main() { ifstream FlujoE("ecuaciones.txt");
// ¿Existe el archivo? if(!FlujoE.is_open()) { cout<<"El archivo \'ecuaciones.txt\' no se ha podido cargar." "\nAsegurese de su existencia, y vuelva a iniciar el programa."<<endl; return 1; }
// ¿Sí? Entonces lo procesamos. string linea; int K = 0, flag; while(FlujoE.good()) // Método más general que eof() { getline(FlujoE, linea); if( (flag=procesarLinea(linea, K)) != 0) // Si ocurrió algo inesperado. Mostrar razón y finalizar. { cout<<razon[flag-1]; return 0; } ++K; } for(size_t i=0; i<Eq.size(); ++i) { if(Eq[i].coefX == Eq[i].coefY && Eq[i].coefY == 0) { if(Eq[i].cte != 0) { cout<<"El sistema de ecuaciones no presenta solucion alguna."<<endl <<"Esto es por la inconsistencia de una ecuacion de la forma:"<<endl <<"0x+0y+C=0 donde C es distinto de cero."<<endl; return 0; } else // Eliminamos la ecuación 0x+0y+0=0. { Eq.erase(Eq.begin() + i); --i; continue; } } SimplifyEq(&Eq[i]); //cout<<"Ecuacion "<<i<<" simplificada: "; //printEq(Eq[i]); cout<<endl; }
// Buscamos Ec equivalentes y borramos repetidas. for(size_t i=0; i<Eq.size()-1; ++i) for(size_t j=i+1; j<Eq.size(); ++j) if(EcEquivalentes(Eq[i], Eq[j])) { Eq.erase(Eq.begin() + j); --j; }
cout<<"El sistema es equivalente a ... "<<endl; for(size_t i=0; i<Eq.size(); ++i) printEq(Eq[i]); cout<<"... luego de haber simplificado las ecuaciones y eliminado las equivalentes."<<endl<<endl;
// Si se registran más de 2 Ec únicas, no presenta sol el sistema. switch( Eq.size() ) { case 0: cout<<"El sistema presenta infinitas soluciones (X e Y reciben cualquier valor)."<<endl; break; case 1: if(Eq[0].coefX==0) cout<<"Y = "<<-Eq[0].cte/Eq[0].coefY<<", X pertenece a los reales."<<endl; else if (Eq[0].coefY==0) cout<<"X = "<<-Eq[0].cte/Eq[0].coefX<<", Y pertenece a los reales."<<endl; else // Ax+By+C=0 donde A,B!=0 cout<<"El sistema presenta infinitas soluciones, siempre que se satisfaga: "<<endl <<"Y = "<<-Eq[0].cte/Eq[0].coefY<<" "<<-Eq[0].coefX/Eq[0].coefY<<"X"<<endl; break; case 2: { bool sehizo = false; // Usamos variables más cortas. float A=Eq[0].coefX, B=Eq[0].coefY, C=Eq[0].cte; // Ax+By+C=0 float D=Eq[1].coefX, E=Eq[1].coefY, F=Eq[1].cte; // Dx+Ey+F=0 float X, Y; // Solución al sistema.
if(A!=0 && B!=0 && D!=0 && E!=0) { Y = (C*D - A*F)/(A*E - D*B); X = (-B/A)*Y - C/A; cout<<"X = "<<X<<", Y = "<<Y<<"."<<endl; }
coefNulo: if(A==0) { if(C==0) Y=0; else Y = -C/B; if(D==0) { if(F==0) { if(Y!=0) cout<<"Las ecuaciones son contradictorias. El sistema no presenta solucion."<<endl; else cout<<"Y = "<<Y<<", X pertenece a los reales."<<endl; // "Y = 0" } else { if(Y!=-F/E) cout<<"Las ecuaciones son contradictorias. El sistema no presenta solucion."<<endl; else cout<<"Y = "<<-F/E<<", X pertenece a los reales."<<endl; // "Y = "<<Y } } else // D!=0 { if(E==0) { if(F==0) cout<<"Y = "<<Y<<", X = 0."<<endl; else cout<<"Y = "<<Y<<", X = "<<-F/D<<"."<<endl; } else // E!=0 { if(F==0) cout<<"Y = "<<Y<<", X = "<<E*Y/D<<"."<<endl; else cout<<"Y = "<<Y<<", X = "<<(-E*Y - F)/D<<"."<<endl; } } } else // A!=0 if(B==0) { if(C==0) X=0; else X=-C/A;
if(D==0) { if(F==0) cout<<"Y = 0, X = "<<X<<"."<<endl; else cout<<"Y = "<<-F/E<<", X = "<<X<<"."<<endl; } else // D!=0 { if(E==0) { if(F==0) if(X!=0) cout<<"Las ecuaciones son contradictorias. El sistema no presenta solucion."<<endl; else cout<<"X = 0, Y pertenece a los reales."<<endl; else // F!=0 if(X!=-F/D) cout<<"Las ecuaciones son contradictorias. El sistema no presenta solucion."<<endl; else cout<<"X = "<<-F/D<<", Y pertenece a los reales."<<endl; } else // E!=0 { if(F==0) cout<<"X = "<<X<<", Y = "<<D*X/E<<"."<<endl; else cout<<"X = "<<X<<", Y = "<<(-D*X - F)/E<<"."<<endl; } } }else if(!sehizo){ // B!=0 // Evaluamos lo mismo empezando por la otra Ec. float tempo; tempo=A; A=D; D=tempo; tempo=B; B=E; E=tempo; tempo=C; C=F; F=tempo; sehizo=true; goto coefNulo; } } // Necesario usar corchetes cuando se declaran variables dentro de un case. break;
default: cout<<"El sistema presenta mas de 2 ecuaciones unicas, por lo tanto no tiene solucion."<<endl; } return 0; }
void SimplifyEq(Ecuacion *Ec) { // Encontramos el menor. Pero si es 0, considerar el siguiente menor. int coefX = Ec->coefX; if(coefX<0) coefX*=-1; int coefY = Ec->coefY; if(coefY<0) coefY*=-1; int cte = Ec->cte; if(cte<0) cte*=-1;
if(coefX==coefY && coefY==cte) { // No es necesario verificar que cte!=0. Ello se evalúa antes de intentar simplificarla. Ec->coefX/=cte; Ec->coefY/=cte; Ec->cte/=cte; return; }
int menor; // Su valor depende de la forma de la Ec (8 casos: 2x2x2). Ya que son 3 variables que pueden ser o no nulas. // Los casos 0,0,0 y 0,0,N ya se descartaron antes. if(cte==0) { if(coefX == 0) return; // 0x+By+0=0 => y=0 if(coefY == 0) return; // Ax+0y+0=0 => x=0 // En este pto, la Ec es Ax+By=0 menor = coefX<coefY ? coefX : coefY; } else { if(coefX==0) // By+C=0 menor = coefY<cte ? coefY : cte; else if (coefY==0) // Ax+C=0 menor = coefX<cte ? coefX : cte; else // Necesariamente Ax+By+C=0 donde A,B,C !=0 { menor = coefX; if(coefY<menor) menor=coefY; if(cte<menor) menor=cte; } }
// Usamos la variable menor como centinela. if(menor!=2 && menor%2==0) menor/=2; // Para evitar tanto proceso. while(menor>1) { while(Ec->coefX%menor==0 && Ec->coefY%menor==0 && Ec->cte%menor==0) { //cout<<"Se dividio entre "<<menor<<endl; Ec->coefX /= menor; Ec->coefY /= menor; Ec->cte /= menor; } --menor; } }
unsigned procesarLinea(string linea, unsigned K) { Ecuacion EqTemp = {0,0,0}; /* Las Eq pueden ser: 3x+4y=7 2x-6=0 1y+2=0 2y=6x+3 1x=-3y+1 */
// Suprimimos todos los vacíos. while( linea.find(' ') != string::npos ) linea.erase( linea.find(' ') );
if( linea.find('=') == string::npos ) return 1; // Falta signo de igualdad en la Eq. else if ( linea.find('=') == linea.size()-1 ) return 2; // No hay nada después del igual.
if( linea.find('x') == 0 || linea.find('y') == 0 ) return 3; // Variables sin coeficiente antepuesto.
for(size_t i=0; i<linea.size(); ++i) { if( !isdigit(linea[i]) && linea[i]!='=' && linea[i]!='+' && linea[i]!='-' && linea[i]!='x' && linea[i]!='y') return 4; // No es un número, ni símbolo aritmético. }
// Ec que continienen algo como "2x3x" o "42y10y". string STRtempo = linea; for(short i=0; i<STRtempo.size(); ++i) if( isdigit(STRtempo[i]) ) STRtempo.erase(i--, 1);
for(size_t i=0; i<STRtempo.size()-1; ++i) if( (STRtempo[i]=='x' && STRtempo[i+1]=='x') || (STRtempo[i]=='y' && STRtempo[i+1]=='y') ) return 5;
// Encontramos el coeficiente de x: short pos = linea.find('x'); string s; while( pos != string::npos ) // Si se encontró alguna x, { // obtenemos su coeficiente y borramos su rastro. --pos; // Retrocedemos una pos antes de 'x'. while(pos>=0) { if( isdigit(linea[pos]) ) s.insert(s.begin(), linea[pos--]); else if(linea[pos]=='+' || linea[pos]=='-') { s.insert(s.begin(), linea[pos--]); break; } else if(linea[pos]=='=') break; }
//cout<<"String de algun coefX de "<<K<<": "<<s<<endl; if( linea.find('x') < linea.find('=') ) EqTemp.coefX += atoi(s.c_str()); else EqTemp.coefX -= atoi(s.c_str());
linea.erase(pos+1, linea.find('x')-pos); //cout<<"Ecuacion recortada: "<<linea<<endl; pos = linea.find('x'); s.clear(); }
// Ahora el coeficiente de y: pos = linea.find('y'); while( pos != string::npos ) // Si se encontró alguna y, { // obtenemos su coeficiente y borramos su rastro. --pos; // Retrocedemos una pos antes de 'y'. while(pos>=0) { if( isdigit(linea[pos]) ) s.insert(s.begin(), linea[pos--]); else if(linea[pos]=='+' || linea[pos]=='-') { s.insert(s.begin(), linea[pos--]); break; } else if(linea[pos]=='=') break; }
if( linea.find('y') < linea.find('=') ) EqTemp.coefY += atoi(s.c_str()); else EqTemp.coefY -= atoi(s.c_str());
linea.erase(pos+1, linea.find('y')-pos); pos = linea.find('y'); s.clear(); } // Ahora la constante de la ecuacion: pos = linea.size()-1; while(pos>0) { if( isdigit(linea[pos]) ) s.insert(s.begin(), linea[pos--]); else if(linea[pos]=='+' || linea[pos]=='-') { s.insert(s.begin(), linea[pos--]); if( pos >= linea.find('=') ) EqTemp.cte -= atoi(s.c_str()); else EqTemp.cte += atoi(s.c_str()); s.clear(); } else // Obligatoriamente será '=' { --pos; if(s.size()>0) { EqTemp.cte -= atoi(s.c_str()); s.clear(); } } }
// pos es 0. if(s.size()>0) { if(linea[0]=='=') EqTemp.cte -= atoi(s.c_str()); else EqTemp.cte += atoi(s.c_str()); s.clear(); }
Eq.push_back(EqTemp); return 0; }
void printEq(Ecuacion Ec) { if(Ec.coefX!=0) cout<<Ec.coefX<<"X ";
if(Ec.coefY>0) cout<<"+ "<<Ec.coefY<<"Y "; else if(Ec.coefY<0) cout<<Ec.coefY<<"Y ";
if(Ec.cte>0) cout<<"+ "<<Ec.cte; else if(Ec.cte<0) cout<<Ec.cte;
cout<<" = 0"<<endl; }
bool EcEquivalentes(Ecuacion A, Ecuacion B) { if(A.coefX==B.coefX && A.coefY==B.coefY && A.cte==B.cte) return true; else return false; }
|
He tratado de cubrir todos los vacíos posibles. Sin embargo, sigo pensando que es una solución un poco extraña. (No imaginé que me fuera a extender tanto con este enunciado...)
Un ejemplo de más o menos cómo funciona (si la entrada no tiene errores, ya que en esos casos debería advertir):
Entrada.
| Cita: | 2x+1y=2x+1y 2x+2y=4 2y=-5+2-1y |
Salida.
| Cita: | El sistema es equivalente a ... 1X + 1Y -2 = 0 + 1Y + 1 = 0 ... luego de haber simplificado las ecuaciones y eliminado las equivalentes.
Y = -1, X = 3.
Process returned 0 (0x0) execution time : 0.010 s Press any key to continue. |
Si alguien encuentra errores me lo hacen saber... y pues, si tienen sugerencias también  |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |