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 - Rockmore

#1
Bueno, tras un poco más de investigación y consultas, lo que fallaba principalmente en el código estaba en el constructor de copia y en la sobrecarga del operador asignación. Como se puede comprobar, ambos crean la estructura de las matrices, pero no les dan el valor de la matriz origen, por tanto, quedan en basura y provocan el mal funcionamiento. Este es el código reescrito:
Código (cpp) [Seleccionar]
......
......
    //Constructor de copia
    Matriz (const Matriz &matriz){
        NF=matriz.NF;
        NC=matriz.NC;
        //Estructura de matriz
        M=new int *[NF];
        for(int i=0;i<NF;i++){
            M[i]=new int[NC];
        }
        //Contenido de matriz
        for(int k=0;k<NF;k++){
            for(int l=0;l<NC;l++){
                M[k][l]=matriz.M[k][l];
            }
        }
    }
.....
......
    //Operador asignacion
    Matriz operator = (Matriz m){
        if(NF!=m.NF){
            for(int i=0;i<NF;i++){
                delete []M[i];
            }
            delete []M;
        }
        //Estructura de matriz
        NF=m.NF;
        NC=m.NC;
        M=new int *[NF];
        for(int j=0;j<NF;j++){
            M[j]=new int [NC];
        }
        //Contenido de matriz
        for(int k=0;k<m.NF;k++){
            for(int l=0;l<m.NC;l++){
                M[k][l]=m.M[k][l];
            }
        }
        return(*this);
    }
.....
......


El tema del return no tiene nada que ver. Igual es por el compilador que utilizo, pero no tengo problemas con los paréntesis ni sin ellos. Gracias por el interés, de todos modos.

Sin embargo, creo que nunca descubriré por qué devolvía 3.... :-\
#2
Saludos. A día de hoy me encuentro realizando un programilla que realice operaciones sencillas con matrices. Concretamente, sumas, restas y multiplicaciones. Como todos sabemos, para sumar o restar matrices, deben ser del mismo tamaño, y para multiplicarlas, el número de columnas de la primera debe ser igual al número de filas de la segunda. En este programa en concreto, si no se dan esas características, la operación debe devolver una matriz nula, de 0x0 elementos. Pongo la parte interesante del código y sigo con el problema:
Código (cpp) [Seleccionar]
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

using namespace std;

//Clase Matriz
class Matriz{
protected:
    int **M;
    int NF,NC;
public:
    //Constructor por defecto
    Matriz (){
        NF=0;
        NC=0;
        M=NULL;
    }
    //Constructor de copia
    Matriz (const Matriz &matriz){
        NF=matriz.NF;
        NC=matriz.NC;
        M=new int *[NF];
        for(int i=0;i<NF;i++){
            M[i]=new int[NC];
        }
    }
    //Constructor con parametros
    Matriz (int nf, int nc){
        M=new int *[nf];
        for(int i=0;i<nf;i++){
            M[i]=new int[nc];
        }
        for(int i=0;i<nf;i++){
            for(int j=0;j<nc;j++){
                M[i][j]=rand()%51;
            }
        }
        return;
    }
    //Destructor
    ~Matriz(){
        for(int i=0;i<NF;i++){
            delete M[i];
        }
        return;
    }
    //Operador asignacion
    Matriz operator = (Matriz m){
        if(NF!=m.NF){
            for(int i=0;i<NF;i++){
                delete M[i];
            }
        }
        NF=m.NF;
        NC=m.NC;
        M=new int *[NF];
        for(int j=0;j<NF;j++){
            M[j]=new int [NC];
        }
        return(*this);
    }
    //Sobrecarga de operador de salida
    friend ostream& operator <<(ostream &medio, Matriz matriz){
        for(int i=0;i<matriz.NF;i++){
            for(int j=0;j<matriz.NC;j++){
                cout<<matriz.M[i][j]<<" ";
            }
            cout<<endl;
        }
        return(medio);
    }
    //Sobrecarga de operador suma
    Matriz operator + (Matriz m){
        Matriz resul;
        if(NF==m.NF&&NC==m.NC){
            for(int i=0;i<NF;i++){
                for(int j=0;j<NC;j++){
                    resul.M[i][j]=M[i][j]+m.M[i][j];
                }
            }
        }
        return(resul);
    }
    //Sobrecarga de operador resta
    Matriz operator - (Matriz m){
        Matriz resul;
        if(NF==m.NF&&NC==m.NC){
            for(int i=0;i<NF;i++){
                for(int j=0;j<NC;j++){
                    resul.M[i][j]=M[i][j]-m.M[i][j];
                }
            }
        }
        return(resul);
    }
    //Sobrecarga de operador producto
    Matriz operator * (Matriz m){
        Matriz resul;
        if(NC==m.NF){
            int N=NC;
            for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    resul.M[i][j]=0;
                    for(int k=0;k<N;k++){
                        resul.M[i][j]=resul.M[i][j]+M[i][k]*m.M[k][j];
                    }
                }
            }
        }
        return(resul);
    }
};

int main(void){
    //Reinicio de semilla
    srand(time(0));
    //Prueba de codigo
    Matriz m1(5,5),m2(5,5);
    cout<<"Matriz 1 + Matriz 2 ="<<endl<<m1+m2;
    getche();
    return(0);
}


Como se puede observar, el constructor con parámetros crea una matriz de NFxNC elementos, los cuales son valores aleatorios entre 0 y 50. El caso es que al probar la suma, y a pesar del getche(), el programa se ejecuta y se cierra automáticamente, y lo más extraño de todo, me devuelve 3. Es curioso, porque aunque no se realizara bien la operación, debería devolver 0, ya que compila sin problemas, pero devuelve 3. Por otro lado, si las matrices declaradas en main no llevan parámetros, el programa se ejecuta con normalidad, mostrando el texto del cout sin matriz (porque es nula), espera que pulse una tecla para continuar y devuelve 0. Por tanto, puedo suponer que el problema está, bien en el envío de parámetros, en el constructor de copia, o incluso en la sobrecarga del operador suma, pero no acabo de verlo. Por si sirve de algo, el compilador que utilizo es el QtCreator de Nokia.

Gracias por vuestra paciencia ;)
#3
Bueno, después de darle mil vueltas logré encontrar los dos fallos que había, como siempre, tonterías, pero que hacen que te vuelvas loco.
Para empezar, el símbolo > funciona, el tema es que el booleano centinela no estaba inicializado, por tanto, no entraba en el bucle de ordenación. Por otro lado, el bucle interno empezaba en j=0, cuando debía hacerlo en j=1. El código resultante del método es el siguiente.
Código (cpp) [Seleccionar]
//Metodo reordenacion de contactos
    void Ordenar(void){
        Contacto aux;
        bool centinela=true;
        for(int i=0;i<N&&centinela;i++){
            centinela=false;
            for(int j=1;j<N;j++){
                if(lista[j-1].VerNombre()>lista[j].VerNombre()){
                    aux=lista[j];
                    lista[j]=lista[j-1];
                    lista[j-1]=aux;
                    centinela=true;
                }
            }
        }
        return;
    }

De todos modos, gracias por el aporte. Lo tendré en cuenta para futuros programas, que se avecinan chungos.  ;)
#4
Saludos. Liado ando con un gestor de agenda, en el que he de reordenar por nombre los contactos cada vez que añado uno nuevo. Por supuesto, pensé en la burbuja, pero, a pesar de que compila sin problemas, no reordena nada. He aquí mi código:
Código (cpp) [Seleccionar]
//Clase Agenda
class Agenda{
private:
    Contacto *lista;
    int N;
public:
    //Constructor por defecto
    Agenda(){
        N=0;
        lista=NULL;
        return;
    }
    //Destructor
    ~Agenda(){
        if(lista){
            delete[]lista;
        }
    }
    //Metodo aniadir contacto
    void NuevoContacto(void){
        //Creacion vector Contacto auxiliar
        Contacto *aux=new Contacto[N+1];
        //Recoleccion de datos anteriores
        for(int i=0;i<N;i++){
            aux[i]=lista[i];
        }
        //Peticion de dato nuevo
        cin>>aux[N];
        cin>>aux[N].fnac;
        cin>>aux[N].dir;
        //Eliminacion de vector Contacto obsoleto
        if(lista!=NULL){
            delete[]lista;
        }
        //Recreacion de vector Contacto util
        lista=aux;
        N++;
        Ordenar(lista,N);
        return;
    }

//.........

    //Metodo reordenacion de contactos
    void Ordenar(Contacto listado[], int n){
        Contacto aux;
        bool centinela;
        for(int i=0;i<n&&centinela==true;i++){
            centinela=false;
            for(int j=0;j<n;j++){
                if(listado[j-1].VerNombre()>listado[j].VerNombre()){
                    aux=listado[j-1];
                    listado[j-1]=listado[j];
                    listado[j]=aux;
                    centinela=true;
                }
            }
        }
        return;
    }
};

¿Dónde está el fallo?
#5
Bueno, ya está resuelto. El error estaba en que inicializaba N en -1, para luego añadirle 1 antes de crear un contacto nuevo. Queda solucionado inicializando N en 0 y añadirle 1 DESPUES de crear el contacto.

Código (cpp) [Seleccionar]
class Agenda{
private:
    int N;
    Contacto lista1[NMAX];
public:
    //Constructor por defecto
    Agenda(void){
        N=0;
    }
    //Metodo anyadir contacto
    void NuevoContacto(void){       
        lista1[N].Solicitar();
        N++;
        return;
    }
    //Metodo muestra de contactos
    void ListarContactos(void){
        //Condicion de vector Contacto vacio
        if(N<0){
            cout<<"No hay contactos guardados"<<endl;
            getche();
        }
        else{
            for(int i=0;i<=N;i++){
                cout<<"Contacto n. "<<i+1<<endl;
                lista1[i].Mostrar();
                getche();
            }
        }
        return;
    }
    //Metodo busqueda de contactos
    void BuscarContacto(void){
        string buscar,comparar;
        bool exito=false;
        cout<<"Nombre a buscar: ";
        getline(cin,buscar);
        for(int j=0;j<N;j++){
            //Busqueda de comparador
            comparar=lista1[j].VerNombre();
            //Comprobante
            cout<<comparar<<endl;
            //Comparador de nombres
            if(buscar==comparar){
                lista1[j].Mostrar();
                //Centinela de contacto encontrado
                exito=true;
            }
        }
        if(exito==false){
            cout<<"Contacto no encontrado"<<endl;
        }
        return;
    }
};


De todos modos, gracias por las ideas  ;)
#6
Pues sí, soy de la UA, del grupo de tarde de teleco. Me has pillado. Pues espero tu código, que a mí se me ha secado el cerebro.
#7
Saludos. Gracias por las aportaciones. Por un lado, los atributos deben ser todos privados, así que no puedo hacer ese público. Por otro lado, añadí un método público en "Contacto" que me devolviera el string nombre. Así no tengo errores de compilación ni de ejecución, sin embargo, es posible que no lo haya creado bien, pues cuando voy a buscar un contacto que he añadido, no me encuentra nada. Ni siquiera me salta el centinela, pues me dice "Contacto no encontrado".
Código (cpp) [Seleccionar]
class Contacto
{
private:
    string nombre, apellidos;
    FechaNacimiento fnac1;
    Direccion dir1;
public:
    string VerNombre(void)
    {
        return(nombre);
    }

    void Mostrar(void)
    {
        cout<<"Nombre: "<<nombre<<endl;
        cout<<"Apellidos: "<<apellidos<<endl;
        fnac1.Mostrar();
        dir1.Mostrar();
        return;
    }
    void Solicitar(void)
    {
        cout<<"Nombre: ";
        getline(cin,nombre);
        cout<<"Apellidos: ";
        getline(cin,apellidos);
        fnac1.Solicitar();
        dir1.Solicitar();
        return;
    }
};

class Agenda
{
private:
    int N;
    Contacto lista1[NMAX];
    string buscar,comparar;
    bool exito;
public:
    Agenda(void)
    {
        N=-1;
        exito=false;
    }
    void NuevoContacto(void)
    {
        N++;
        lista1[N].Solicitar();
        return;
    }
    void ListarContactos(void)
    {
        if(N<0)
        {
            cout<<"No hay contactos guardados"<<endl;
            getche();
        }
        else
        {
            for(int i=0;i<=N;i++)
            {
                cout<<"Contacto n. "<<i+1<<endl;
                lista1[i].Mostrar();
                getche();
            }
        }
        return;
    }
    void BuscarContacto(void)
    {
        cout<<"Nombre a buscar: ";
        getline(cin,buscar);
        for(int j=0;j<N;j++)
        {
            comparar=lista1[j].VerNombre();
            if(buscar==comparar)
            {
                lista1[j].Mostrar();
                exito=true;
            }
        }
        if(exito==false)
        {
            cout<<"Contacto no encontrado"<<endl;
        }
        return;
    }
};
#8
Saludos. Puede que el título no esté muy claro, así que explicaré cuál es el problema que me ha traído:

En una clase Agenda he de crear un método mediante el cual el usuario introduzca un nombre y el programa muestre todos los datos del vector en los que se encuentre ese nombre. El caso es que el nombre se encuentra en otra clase distinta, y no podemos hacer amigos. Busqué información y descubrí que es posible hacerlo con los métodos get y set, pero no sé cómo aplicarlos.

Aquí pongo parte del código:
Código (cpp) [Seleccionar]
class Contacto
{
private:
    string nombre, apellidos;
    FechaNacimiento fnac1;
    Direccion dir1;
public:
    void Mostrar(void)
    {
        cout<<"Nombre: "<<nombre<<endl;
        cout<<"Apellidos: "<<apellidos<<endl;
        fnac1.Mostrar();
        dir1.Mostrar();
    }
    void Solicitar(void)
    {
        cout<<"Nombre: ";
        getline(cin,nombre);
        cout<<"Apellidos: ";
        getline(cin,apellidos);
        fnac1.Solicitar();
        dir1.Solicitar();
    }
};

class Agenda
{
private:
    int N;
    Contacto lista1[NMAX];
    string buscar;
    bool exito;
public:
    Agenda(void)
    {
        N=-1;
        exito=false;
    }
    void NuevoContacto(void)
    {
        N++;
        lista1[N].Solicitar();
    }
//...
//Codigo entre medias
//...
    void BuscarContacto(void)
    {
        cout<<"Nombre a buscar: ";
        getline(cin,buscar);
        for(int j=0;j<N;j++)
        {
            if(lista1[j].nombre==buscar)//Esta condicion no es correcta
            {
                lista1[j].Mostrar();
                exito=true;//Centinela de contacto encontrado
            }
        }
        if(exito==false)
        {
            cout<<"Contacto no encontrado"<<endl;
        }
    }
};
#9
Saludos. Sigo con el black jack avanzando a mi ritmo, pero con otra traba. Y si resuelvo esto, el resto del programa lo doy por solucionado.

Bien, resulta que el formato de salida debe ser algo como:

"BLACK JACK

Tus cartas: 1 3 J 2 8

Valor total: 25

Deseas otra carta?"

Según este ejemplo, la primera jugada debe mostrar las dos primeras cartas, el valor total y la pregunta de coger otra carta, y al decir que sí, lo mismo, pero con la siguiente. En definitiva, que mientras aparece el texto de alrededor, primero se muestran dos cartas y luego de una en una.

Mi idea al hacer el código fue poner el primer texto de modo forzado, directamente con printf y punto, y las siguientes cartas ya en un do while. Esto es lo que tengo hecho de momento:

        system("cls");
        printf("**************");
        printf("\n* BLACK JACK *");
        printf("\n**************");
        printf("\nTus cartas: ");
        if(baraja[0]==11){
            printf("J ");
            val=10;
        }else if(baraja[0]==12){
            printf("Q ");
            val=10;
        }else if(baraja[0]==13){
            printf("K ");
            val=10;
        }else{
            printf("%d ",baraja[0]);
            val=baraja[0];
        }
        cartas=cartas+val;

        for(i=1;cartas<21;i++){
            if(baraja[i]==11){
                printf("J ");
                val=10;
            }else if(baraja[i]==12){
                printf("Q ");
                val=10;
            }else if(baraja[i]==13){
                printf("K ");
                val=10;
            }else{
                printf("%d ",baraja[i]);
                val=baraja[i];
            }
            cartas=cartas+val;
            printf("\n\nEl valor de tus cartas es: %d",cartas);
        }


La teoría es buena, obviando el hecho de que de este modo no se muestre el resto del texto, sin embargo, lo que me sale es algo como:

"BLACK JACK

Tus cartas: 1 3

J lor total: 4

2 lor total: 14

Valor total: 16"

Es decir, que sobreescribe la línea de valor total de la anterior tirada.

Una cosa que se me ocurrió fue meter todo el texto en un for o un do while, que borrase todo y lo volviera a escribir, aunque se me presentaban dos problemas: el primero, no saldrían las dos primeras cartas de golpe, y el segundo, que probablemente sólo saliera la última carta, pese a que cambie el valor total.
#10
Cierto, qué error más tonto. Había creado un bucle infinito por una letrita de nada.
¡Muchas gracias!