Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - K-YreX

#411
Programación C/C++ / Re: Clase pila estática
30 Octubre 2019, 22:52 PM
Bueno, a ver. Lo primero es que en la imagen estás usando un constructor de Pila que recibe un parámetro (int) y ese constructor no sé qué hace por lo que supondré que el parámetro es el tamaño de la pila y el constructor sin parámetros pone un tamaño estándar de 3.

Los <new> y los <delete> no se usan a lo loco pensando "así me aseguro de que hay espacio reservado", no. Tienes que saber cuando hay espacio reservado y cuando no, reservar la memoria justa y necesaria y liberarla correctamente.

Los constructores son las funciones que llaman los objetos cuando se crean. Estos objetos como justo se están creando no tienen nada todavía por lo que sí necesitas reservar memoria. El de por defecto está bien, el de con parámetros supondré que también pero el de copia no. Cuando creas una instancia con el constructor de copia, no le estás asignando espacio.
Código (cpp) [Seleccionar]

Pila miPila1(5); // sigo suponiendo que esto es una pila de longitud 5
Pila miPila2(miPila1); // miPila2 no tiene memoria reservada para el array interno


El destructor como bien dices debe liberar la memoria de esa Pila. Y es más, no necesitas <Vaciar()> la Pila; con liberar la memoria reservada sería suficiente.

La función <Copiar()> no está bien. Esa función la usarás siempre sobre instancias que has creado antes por lo que ya tienen memoria reservada. La duda es: tendrá el mismo tamaño la Pila sobre la que copias que la Pila que copias? Es algo que no puedes asegurar si puedes crear Pilas de distintos tamaños por lo que lo que tendrías que hacer es liberar la memoria de la que quieres copiar y asignarle la misma longitud que a la otra nuevamente (pero sin olvidar primero liberar la memoria que ya tenía).
Código (cpp) [Seleccionar]

Pila pilaTam5(5); // se reserva memoria para 5 elementos
Pila pilaTam10(10); // se reserva memoria para 10 elementos
pilaTam5.Copiar(pilaTam10); // la funcion Copiar() tiene que borrar la memoria para 5 elementos y crear nueva memoria para 10


El operador = está bien ya que haces lo que te digo para la función <Copiar()> pero claro, lo de borrar la memoria que tenía y crear memoria nueva... una de dos, o lo haces dentro de la función <Copiar()> o lo haces fuera pero no lo hagas dos veces.




EDIT: Si las funciones <Altura()> y <Altura2()> son para mostrar el tamaño de la Pila, no tiene sentido que las hagas externas a la clase y reciban la Pila como parámetro. Es mejor que las hagas dentro de la clase y que no crees dos funciones diferentes para lo mismo.
#412
Si quieres recibir ayuda de alguien, pónselo un poco más fácil a quien te intente ayudar...
Es un código bastante grande, la tabulación está regular y sin resaltado de sintaxis (en la etiqueta de apertura de code puedes poner "=c" o "=cpp" sin comillas para que se resalte la sintaxis de C o de C++ o directamente elegir el lenguaje del desplegable "Código GeSHi"). Además no especificas nada de tu problema. Obligas a quien te quiera ayudar a leerse el código entero... y te aseguro que no es para nada apetecible.
#413
Programación C/C++ / Re: Clase pila estática
30 Octubre 2019, 16:47 PM
Te recomiendo cuando pongas un código en el que tienes problemas que lo copies del original. No sería la primera vez que el código está mal escrito, al escribirlo aquí se escribe bien y es imposible detectar el error.
Aunque en este caso veo un par de problemas:
  • Si en el constructor asignas siempre un tamaño de 3 al array que usas como contenedor para la pila, es mejor que directamente lo hagas de forma estática (v[MAX]) en vez de usar un puntero y asignarlo de forma dinámica (te ahorrarás de tener que liberar la memoria dinámica manualmente cosa que parece que no haces).
  • En el constructor reservas memoria para el array pero... y en el constructor de copia?? En ningún momento estás reservando memoria. Tienes que pensar qué estado tendrá un objeto cuando llama a una función. En el caso de los constructores, son objetos que todavía no se han creado (se crean con el constructor) entonces todavía no tienen memoria reservada. Aprovecho para decirte que pienses cómo debería funcionar la función <Copiar()> (si debería reservar memoria o no).
  • La función <Cimapila()> no funciona bien. Estás perdiendo el valor del tope y devolviendo un valor basura.
#414
Programación C/C++ / Re: Clase pila estática
30 Octubre 2019, 02:24 AM
Cita de: GominaTilted en 29 Octubre 2019, 18:59 PM
Muchas gracias. No había pensado que podía usar las funciones sobre el propio objeto, muchas horas delante de esto xD.
Esa es precisamente la utilidad de las funciones miembro de una clase: actuar sobre el objeto/instancia que las llama de forma implícita.


Cita de: GominaTilted en 29 Octubre 2019, 21:22 PM
Vengo con la última duda, pensaba que había acabado pero no :(. He intentado hacer la sobrecarga del operador =. Tengo esto:


const Pila& Pila::operator= (const Pila & p)
{
    Vaciar(); //vacía la pila objeto
    Copiar(p); //copia la p en la pila objeto.
    Return p;
}


Creo que está bien, pero al compilar la línea p = p2 (siendo p una pila llena con valores {1...4} y p2 una pila vacía), salta el error "exited, segmentation fault".
Es mejor que añadas también el código de las funciones que intervengan en todo el proceso de alguna manera u otra para saber dónde está el fallo exactamente.
Además ten cuidado con las mayúsculas. Suele ser habitual usar la nomenglatura UpperCamelCase (que como se nota en el nombre, cada palabra empieza por mayúscula, para designar clases) y la nomenglatura lowerCamelCase (todas las palabras empiezan por mayúscula menos la primera) para funciones. Esto es una convención, no son reglas estrictas pero en el caso del <return> si es necesario ya que C++ es un lenguaje sensible a mayúsculas y minúsculas (no es lo mismo escribir una palabra usando mayúsculas que minúsculas).
#415
Programación C/C++ / Re: Clase pila estática
29 Octubre 2019, 17:41 PM
Lo que tú tienes es una función miembro de una clase, por lo tanto esa función se la aplicas a una pila que ya existe, no tienes que crear una Pila dentro de la función.
La Pila p1 es local a esa función. Tú tienes que trabajar con el objeto implícito que llama a la función <Copiar()>.
Además de eso si estás pasando como parámetro una Pila <p> por referencia y constante, no puedes desapilarla porque es constante.
Código (cpp) [Seleccionar]

void Pila::copiar(Pila p){
   while(!p.vacia()){
       apilar(p.cimaPila());
       p.desapilar();
   }
}



EDIT: Además si lo haces de esa forma estás invirtiendo las pilas.
Si tienes una pila original: p = {1,2,3,4,5} y llamas a la función copiar con otra pila p2, el resultado sería: p2 = {5,4,3,2,1}
#416
Programación C/C++ / Re: Clase pila estática
29 Octubre 2019, 14:52 PM
El compilador no sabe si sólo estás leyendo o estás modificando algo. Las funciones miembro de la clase que sólo "leen" y no van a modificar nada es recomendable declararlas como constantes (no constante el valor de retorno, sino constante la función). Haciendo esto permites que tanto los objetos constantes como los variables llamen a esa función pero si no lo pones entonces el compilador asume que esa función modifica algo y no te deja usarla con objetos constantes.

Te pongo un pequeño ejemplo para que veas como funciona:
Código (cpp) [Seleccionar]

class Persona{
    private:
        string nombre;
        int edad;

    public:
        Persona(){}

        Persona(string nombre, int edad){
            this->nombre = nombre;
            this->edad = edad;
        }

        string getNombre()const{
            return nombre;
        }

        int getEdad()const{
            return edad;
        }

        const Persona& operator=(const Persona &original){
            Persona *nuevaPersona = new Persona(original.getNombre(), original.getEdad());
            return *nuevaPersona;
        }
};

Como ves en la sobrecarga del operator=, estamos pasando un objeto de tipo Persona constante y por referencia y después estamos llamando a las funciones <getNombre()> y <getEdad()>. Para poder llamar a esas funciones, éstas deben ser constantes. (Puedes probarlo y quitar los <const> de los <get> para que veas que da un error.




Para el tema de la recursividad tienes que pensar en que el/los parámetros que le pases a la función tienen que cambiar en algún momento. Entonces para tu caso que quieres calcular el tamaño de la pila puedes hacer lo siguiente:
1º Pensar en el problema sin usar recursividad.
Podrías hacer por ejemplo:

tam := 0
MIENTRAS !pila.vacia HACER
    pila.pop // quitar el elemento del tope
    tam := tam + 1 // sumar uno al tamaño de la pila
FIN MIENTRAS


2º Quitar el bucle.
Para ello tienes que pensar en que cada vez que llames a la función es como una iteración. Y en cada iteración lo que hacías antes era comprobar si estaba vacía y si no lo estaba, eliminabas el tope e incrementabas el tamaño en 1.

Funcion tamRecursivo(Pila pila):int
INICIO
    SI pila.vacia HACER // El caso base (el que termina la recursividad): si la pila esta vacia...
        return 0 // devuelve un 0
    // Si no esta vacia...
    SINO HACER // No hace falta este <else> ya que antes hay un return. Lo pongo para que lo entiendas mejor
        pila.pop // Quitamos un elemento a la pila
        return 1 + tamRecursivo(pila) // Y devolvemos un 1 + el tamaño de la pila al haber quitado un elemento
    FIN SI
FIN

Recuerda no pasar la pila constante ya que la estás modificando ni por referencia ya que entonces te cargarías la original.
#417
Para empezar hay un foro específico para C/C++ así que tu tema seguramente que sea movido.
Dejando eso a un lado, el código ponlo entre etiquetas de Código GeSHi especificando el lenguaje para facilitar la tarea de lectura a los demás.
Y para terminar, no das ningún dato de tu problema, error o lo que tengas. Será más fácil que alguien te ayude si pones el error que te da al compilar (si es que te da alguno) o la parte que no funciona bien (especificando lo que debería hacer y lo que hace, si puedes).
#418
Programación C/C++ / Re: C++
27 Octubre 2019, 02:28 AM
Esto en C++ se realiza usando la programación orientada a objetos. Es decir, mediante una clase.
Código (cpp) [Seleccionar]

class Persona{
    private:
        string nombre;
        int edad;

    public:
        // funciones miembro
};

const int NUM_PERSONAS = 5;

int main(){
    Persona personas[NUM_PERSONAS];

    // dar valores a cada Persona del array

    // ordenar las personas segun su edad
}

Si tienes dudas, consulta en internet sobre el uso de clases en C++ o deja tu código entre etiquetas de Código GeSHi para poder ayudarte.
#419
Programación C/C++ / Re: C++ , duda con vectores
27 Octubre 2019, 01:41 AM
Si estás empezando creo que te puede resultar un poco lioso pero te dejo un par de opciones:
Usar un array auxiliar.
Normalmente esto se hace creando un array auxiliar de punteros. Haciendo que cada puntero i del array auxiliar apunte al elemento i del array original y después ordenas uno de los dos arrays. De esta manera podrás usar el otro para saber cuál era cada elemento.

arrayOriginal  := {3,6,2,9,5}
arrayPunteros := {p0,p1,p2,p3,p4} // pi significa que apunta al elemento i

Entonces ordenas uno de ellos (el de punteros por ejemplo) para dejar el original intacto y quedaría algo así:

arrayOriginal := {3,6,2,9,5}
arrayPunteros := {p2,p0,p4,p1,p3}

Cuando quieras ver qué elemento era, recorres el arrayOriginal. Cuando quieras trabajar con los elementos ordenados, recorres el de punteros.


Para esto tienes que saber un poco sobre trabajar con punteros. Saber usar el operador para desreferenciarlos (*) y esas cosas.
Otra opción más sencilla es usar dos arrays de enteros. Uno que sea el original y el otro que guarde en la posición i, la nueva posición del elemento i original. Con un ejemplo se ve mejor:

arrayOriginal := {3,6,2,9,5}
arrayOrdenOriginal := {0,1,2,3,4}

arrayOrdenado := {2,3,5,6,9}
arrayOrden := {1,4,0,2,3}

Utilizas el array ordenado y cuando quieras saber cuál era el elemento que habías guardado el primero (posición 0: valor 3), lo recuperas porque su nueva posición la indica el arrayOrden (posición 0: valor 1 -> nuevaPosición: arrayOrdenado[1] = 3).
Lo malo de este método es que es más susceptible a errores humanos y que tienes que intercambiar las posiciones en ambos arrays mientras que en el de punteros sólo en uno. Lo bueno es que en este no tienes que trabajar con punteros.

Si no te sirven estas opciones o no entiendes algo. Deja tu código entre etiquetas de Código GeSHi para que podamos ayudarte mejor. :-X
#420
El problema que tienes es matemático, no de programación. A tu consulta le falta información que hay que suponer como que se lanzan dos dados al mismo tiempo, no?
Si esperas que te den el programa terminado, suerte. No creo que lo consigas. Busca información de probabilidad en dados. Ese ejercicio es muy típico y lo encontrarás fácilmente. Cuando lo entiendas, intenta implementarlo en el lenguaje de programación (que tampoco sé si es C o C++) y si entonces tienes problemas es cuando tienes que pedir ayuda por aquí poniendo el código que tengas entre etiquetas de Código GeSHi.