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

#541
Programación C/C++ / Re: Cubos de Nicoman
28 Mayo 2019, 14:59 PM
Para hacer una recurrencia debemos ver qué variables se van modificando en cada iteración y cuál es la condición de salida.
  • Condición de salida (c >= n)
  • Variables que se modifican: <i> <c>

    Ahora las variables que se van modificando las tenemos que incluir como parámetros y el bucle lo tenemos que convertir en un condicional con llamadas recursivas.
    Código (cpp) [Seleccionar]

    size_t cuboNicomanoRecurrente(unsigned numero, unsigned iteracion = 0, unsigned impar = 1){
        if(iteracion < numero-1)
            return numero*(numero-1) + impar + cuboNicomanoRecurrente(numero, iteracion+1, impar+2);
        return numero*(numero-1) + impar;
    }
#542
Para recorrer un arreglo, ya sea estático o dinámico, se hace normalmente pasando el puntero al primer elemento del arreglo y el tamaño de este.

int* buscarMinimo(int *arreglo, const int size){
    int *p_minimo = arreglo; // equivalente a int *p_minimo = &arreglo[0]
    for(size_t i = 1; i < size; ++i)
        if(arreglo[i] < *p_minimo)
            p_minimo = (arreglo+i); // equivalente a p_minimo = &arreglo[i]
    return p_minimo;
}

De esta forma al devolver un puntero al elemento mínimo ya tenemos tanto el valor del elemento <*p_minimo> como su dirección de memoria <p_minimo>.
#543
Programación C/C++ / Re: Ayuda!
27 Mayo 2019, 04:00 AM
@Enzo, parece que no está poniendo el índice i entre corchetes porque al no usar etiquetas de código, eso se traduce como cursiva. Por eso a partir de donde debería estar la i entre corchetes  la letra empieza a salir en cursiva.
Si vas a acabar todos tus mensajes con tu nombre y tu edad, ponlo en tu firma, por lo menos para ahorrarte el escribirlo en cada mensaje  :xD
Y si es cierto que tienes 9 años y que por tanto imagino que estás empezando con la programación, no cojas los malos hábitos desde pequeño, no uses <fflush(stdin)>
#544
Programación C/C++ / Re: Ayuda!
27 Mayo 2019, 00:46 AM
Un array de tamaño n va desde el 0 hasta el n-1, ambos incluidos.
Si el tamaño de esos arrays es 3, tienes que acceder a las posiciones 0,1 y 2 y en ese for estás accediendo a la posición 3 que está fuera de los límites.
#545
Cita de: jorgerengifo en 25 Mayo 2019, 03:21 AM
hola no te entiendo como quedaria el programa para que copile
Pues corrigiendo todos los errores que ha comentado @ivancea96 además de alguno más como que se está usando <costobase> para referirse al miembro privado de la clase cuando en realidad el miembro se llama <base> (bueno o eso es lo que se ha intentado).
Además el <set> y el <get> o se implementan dentro o fuera pero no en los dos sitios...
La verdad es que estoy asombrado con tal cantidad de errores y de este nivel... :o
#546
El problema que tienes es que en el <main> estás pasando como parámetro el tipo de dato, cuando lo que tienes que pasar es el nombre del dato. El tipo solo se indica en el prototipo de la función y en su implementación.
Eso es algo muy muy básico.

En la función <analizarFichero(string)> si le estás pasando el nombre como parámetro, no pidas el nombre dentro de la función. Si lo vas a pedir dentro de la función no se lo pases como parámetro, no sirve de nada.
El <exit (1)> va sin espacio. Es una función que tiene un número como parámetro, no es lo mismo que un <return 1>.

En la función <pedirNumeroPositivo(ifstream)> tienes que pasar el fichero por referencia usando también &.

No te vuelvo a poner ejemplos de cada función porque ya lo hice en el mensaje anterior que publiqué.


Y sí, la función <mostrarPresentacionPrograma()> está bien. Es cierto que no tiene mucho sentido para un <cout> pero normalmente se suele usar para explicar el funcionamiento del programa o cómo hay que usarlo y en caso de que el usuario lo use mal pues se llama a la función de nuevo para que vea cómo se usa.
#547
No voy por orden, la verdad no sé por qué pero te voy comentando las funciones:
Citar
Código (cpp) [Seleccionar]

bool EsPrimo (int num) {
    bool es_primo = false;   
    for (int i = 2; i <= num-1; i++){
       if (num % i == 0){
           return false;
       }
    }
    return num >= 2;
}
En esta función estás creando una variable <bool es_primo = false> que no llegas a usar. Si la creas es para usarla y no usar más de 1 <return> en ese caso como ya te dije, la función quedaría así:
Código (cpp) [Seleccionar]

bool esPrimo(unsigned int numero){
    bool es_primo = true; // suponemos que es primo
    // for(size_t i = 2; i < numero and es_primo; ++i){ // se puede poner asi o como viene a continuacion
    // el for o el while depende de si quieres/te dejan poner dos condiciones dentro del for
    size_t i = 2;
    while(i < numero and es_primo){ // mientras i < numero y numero sea primo
        es_primo = (numero % i != 0); // es primo si el resto es distinto de 0
        i++;
    }
    // llegas aqui cuando i == numero o cuando es_primo = false
    return es_primo;
}

Aquí ves que solo haces un <return> ya que usas la variable <es_primo> como condición de salida o de fin. En el momento que sabes que no es primo, terminas el bucle y retornas el valor que es <false> en ese caso. Si es primo hasta el final, retornas la misma variable que en este caso valdrá <true>.
La línea:
Código (cpp) [Seleccionar]

es_primo = (numero % i != 0);

Es lo mismo que poner:
Código (cpp) [Seleccionar]

if(numero % i == 0)
    es_primo = false;

Por si así lo ves mejor.

En mi caso le estoy pasando como parámetro un <unsigned int numero>, es decir, que no tiene signo, por lo que siempre va a ser positivo. Si a esa función le pasas un <int> (puede ser negativo) te va a salir que cualquier número negativo es primo. Tenlo en cuenta. Esto lo puedes arreglar poniendo:
Código (cpp) [Seleccionar]

bool es_primo = num > 0;
// donde pone
bool es_primo = true;

Para considerar los negativos como no primos. Esto ya a tu gusto o al nivel de lo que te pidan.


Siguiente función:
Citar
Código (cpp) [Seleccionar]

int PedirNumeroPositivo(int num) {
    string archivo;
    while (!archivo.eof()){
        archivo >> num;
    }
}
Aquí tienes varios problemas. Uno es que no puedes aplicar la función <eof()> a <archivo> que es un <string>. Además <num> no es algo que necesites pasar como parámetro. Y esa función retorna un <int> y ahí no retorna nada.
Para poder usar esta función, la función debe conocer el fichero (ifstream) <archivo>. Entonces eso necesitas pasarlo como parámetro. El <num> lo creas dentro de la función y lo retornas al finalizar esta.
Código (cpp) [Seleccionar]

int devolverNumero(ifstream &fichero){
    int numero = 0; // le ponemos un 0 (o lo que queramos) para saber que cuando retorne ese valor es porque el fichero ha llegado a su fin
    if(!fichero.eof())
        fichero >> numero;
    return numero;
}

Esta función devuelve el siguiente número del fichero de entrada <fichero> o 0 si ha llegado al final del fichero. La posición en la que vas del fichero se guarda. Entonces cada vez que llames a esta función, devolverá el número siguiente al que retornó la última vez.
El tema de dónde cerrar el fichero te lo comento más abajo.


La siguiente función es la de <AnalizarFichero()>. Aquí tienes dos opciones que yo veo buenas y no muy complicadas:
  • Opción 1: Pasar el <ifstream> por referencia y devolver un <bool> de si se abrió correctamente o no.
    Parámetros necesarios: ifstream &fichero (le podríamos pasar también el string con el nombre del fichero o se lo podemos pedir dentro de la función al usuario)
    Retorno de la función: bool fichero_correcto
    Código (cpp) [Seleccionar]

    bool analizarFichero(ifstream &fichero){
        string nombre_fichero;
        bool fichero_correcto = true; // suponemos que se va a abrir bien...
        // pedimos el nombre del fichero
        fichero.open(nombre_fichero.c_str());
        if(!fichero) // ...y si no es asi, cambiamos el valor a esa variable <fichero_correcto>
            fichero_correcto = false;
        return fichero_correcto;
    }

    Si quieres pedir el nombre del fichero en el <main> y pasarlo como parámetro, te recomiendo que lo intentes tú. Incluso aunque no lo vayas a usar así, leyendo código no se aprende, se aprende escribiendo código porque ahí es dónde se ven los errores que comete uno y que en código ajeno no ve.
  • Opcion 2: Pasar el nombre como parámetro (o no pasar nada y pedirlo dentro de la función) y retornar un fichero abierto.
    En este caso podemos hacerlo simple, recibimos el nombre como parámetro, creamos un <ifstream> con dicho nombre y lo devolvemos y se acabó.
    Código (cpp) [Seleccionar]

    ifstream abrirFichero(string nombre_fichero){
        ifstream fichero(nombre_fichero.c_str()); // lo mismo que crear el fichero y hacer fichero.open(...)
        // podemos hacer que si el fichero no es valido, termine el programa
        if(!fichero)
            exit(1); // exit termina el programa desde cualquier funcion en la que se ejecute. Pertenece a la libreria <cstdlib>
        // y si no se cumple la condicion anterior, devolvemos el fichero
        return fichero;
    }


    También podemos pedirle nombres al usuario hasta que uno sea correcto:
    Código (cpp) [Seleccionar]

    ifstream abrirFichero(){
        ifstream fichero; // aqui como no conocemos el nombre del fichero todavia usamos open(...) mas abajo
        string nombre_fichero;
        do{ // hacer esto de dentro...
            // pedir nombre fichero y guardarlo en nombre_fichero
            fichero.open(nombre_fichero);
        }   while(!fichero); // ... mientras el fichero no se haya abierto
        // llegamos aqui cuando por fin se ha abierto un fichero de entrada. Entonces lo devolvemos
        return fichero;
    }


    Puedes crear muchas alternativas más, como a ti se te ocurran. Así que te dejo que sigas investigando por tu cuenta. No te limites o copiar y pegar lo que yo he hecho porque así no vas a saber el porqué de cada cosa que hice, ni vas a ver los fallos que cometes al hacerlo tú.


    Por último te dejo algún ejemplo de <main> para que veas como usar las funciones:
    Código (cpp) [Seleccionar]

    int main(){
        // si le vamos a pasar el nombre del fichero como parametro, tendremos que declararlo aqui y pedirselo al usuario
        // como abrir el fichero usando <ifstream abrirFichero()> (el ultimo ejemplo)
        ifstream fichero = abrirFichero(); // sin parametros porque dentro de la funcion es donde le pediremos al usuario el nombre del fichero
        // cuando estemos aqui el fichero ya esta bien abierto
        // como sabemos segun la funcion <int devolverNumero(ifstream &fichero)> que hice arriba que retorna 0 cuando el fichero termina hacemos...
        int numero = devolverNumero(fichero);
        while(numero != 0){
            cout << "El siguiente numero es: " << numero << endl;
            if(esPrimo(numero)) // no hace falta poner == 1 o == true. Ya se entiende si no se pone nada que tiene que valer 1/true
                cout << "El numero " << numero << " es primo" << endl;
            else
                cout << "El numero " << numero << " no es primo" << endl;
            numero = devolverNumero(fichero);
        }
        // el fichero abierto es <fichero> entonces lo cerramos aqui
        fichero.close(); // si se te olvida y no lo cierras tu, ya lo hace el programa al terminar
    }


    Dale vueltas a todo esto que no es poco y practica. Es posible que me haya comido alguna palabra o me haya confundido al escribir algo pero no me apetece revisar todo el mensaje. Suerte :-X :-X
#548
No me voy a poner a revisar el código entero pero...
  • ¿Por qué mezclar C con C++? <printf()>/<cout> <scanf()>/<cin>...
  • ¿Por qué usar <conio.h>? Si lo necesitas para <getch()> tienes, <getchar()> (<cstdio>) o <cin.get()> (<iostream>) No es estándar y a muchos no nos dejará probar ese código al tener esa librería...
  • No uses <system(...)>. Usa <cin.get()> en vez de <system("pause")> y para limpiar la pantalla tienes la alternativa de hacer una función que pinte muchos saltos de línea.
  • <for> de la línea 30... ¿Por qué lo repites 2 veces la acción de asignar una palabra?
  • En la línea 18 yo diría que faltan punteros o... cada variable solo es un <char>?? ¿Por qué no usar <string>?

    Para códigos de ya un cierto tamaño es recomendable empezar a modularizar un poco. Crea funciones que hagan cosas específicas y si tienes problemas con algo solo tienes que mirar la función que se encarga de eso y no todo el código.

    Te dejo un pseudocódigo para que veas cómo lo puedes implementar.

    nivel := 0
    mientras nivel < NIVEL_MAX  and !has_perdido
        vidas := VIDAS_MAX - nivel // asi ya restas una vida al empezar cada nivel. Ten en cuenta que VIDAS_MAX > NIVEL_MAX
        mientras vidas > 0 and !acertado
            jugar()
        fin mientras
        has_perdido = !acertado // si has acertado no pierdes. Si te has quedado sin vidas, si
        si !has_perdido
            nivel := nivel + 1
        fin si
    fin mientras

    Se puede ahorrar alguna variable como <has_perdido> pero lo dejo así para que lo veas mejor.
#549
Citar
Y luego una duda que me surge a la hora de hacer las funciones, mi profesor califica de "Mala práctica" el utilizar más de un Return en cada función, y en por ejemplo en la función EsPrimo (utilizada ya en el ejercicio anterior) he usado 2, pero no sabría como hacerla sin ambos ¿sabes porque es una mala práctica?
Se considera mala práctica en ocasiones porque puede que se te olvide algún <return>. Para evitar esto se suele usar una variable de tipo <bool> (la que tú habías creado en tu código "es_primo" pero que no usabas en la función).
Código (cpp) [Seleccionar]

bool esPrimo(unsigned int numero){
    bool es_primo = true; // suponemos que es primo
    size_t i = 2;
    while(i < numero and es_primo){ // mientras i < numero y numero sea primo
        es_primo = (numero % i != 0); // es primo si el resto es distinto de 0
        i++;
    }
    // llegas aqui cuando i == numero o cuando es_primo = false
    return es_primo;
}



La función para mostrar la presentación del programa está casi bien. Está bien que sea de tipo <void> pero las funciones de tipo <void> no retornan nada. Siempre pones un <return 0>  en todas las funciones y eso solo se pone en el <main>. No tiene sentido hacer funciones que siempre devuelvan 0 y menos si son de tipo <void>.


La función <AnalizarFichero()> es mejor que le añadas algo más como una de las opciones que te di en el mensaje anterior:
Citar
Código (cpp) [Seleccionar]

bool ficheroAbiertoCorrectamente(string nombre_fichero);
// Comprueba si se abrio bien y devuelve true si se abrio bien o false si no se abrio
// Problema: Tenemos que abrir el fichero en la funcion para comprobar si se abrio bien y al salir de la funcion volver a abrirlo otra vez

ifstream abrirFichero(string nombre_fichero);
// Comprueba si se pudo abrir el fichero y en caso de que si, lo devuelve abierto
// Problema: y si no lo pudo abrir? Tendremos que hacer que el programa termine si no se pudo abrir
Yo por ejemplo usaría la segunda opción. Si se abre el fichero correctamente, lo devuelve como parámetro y sino termina el programa con <exit()> (de <cstdlib>).


La función <leerNumero()> la haría que reciba el fichero y devuelva el siguiente valor a leer.
Código (cpp) [Seleccionar]

int leerNumero(ifstream &fichero);
#550
Aparte de los tantos <fflush(stdin)> que no deberían usarse, la función <gets()> que no debería usarse, la función <scanf()> para cadenas que tampoco debería usarse y los nombres de variables para nada específicos que supongo no vas a cambiar porque tú lo entiendes y con que lo entienda el que lo programa ya es suficiente... :silbar:
El problema lo tienes por usar unas veces <gets()> para guardar una cadena de caracteres (deberías usar <fgets()> mejor) y otras veces <scanf()>. <gets()> o su variante más segura <fgets()> guardan el enter del final como un salto de línea; mientras que el <scanf()> no guarda el salto de línea.
Por eso si tú escribes "Pepe" en un <gets()>, estás guardando "Pepe\n" mientras que si escribes "Pepe" en un <scanf()> estás guardando "Pepe". Por eso las cadenas no son iguales.
PD: La función <localizar()> no te va a funcionar como creo que esperas :silbar: