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

#551
Para problemas diferentes mejor abrir un tema nuevo Por si a alguien más le interesa uno de los dos temas...
Lo primero que tienes que pensar es qué funciones quieres usar. Es decir, piensa quiero una función que haga tal cosa y luego piensa cómo implementarla, por ejemplo, quiero una función que me diga si el fichero se pudo abrir correctamente.
  • Qué necesito? Pasarle el nombre del fichero o el propio fichero (yo diría que mejor el nombre).
    Código (cpp) [Seleccionar]

    <retorno> ficheroAbiertoCorrectamente(string nombre_fichero);

    Ahora miramos el retorno.
  • Qué va a hacer la función? Dos posibilidades:
    - El fichero se abre correctamente.
    - El fichero no se abre correctamente.
    Idea 1:
    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

    Si quieres puedes pensar tu propia alternativa, no tiene que ser una de esas dos, pero es para que te hagas una idea. Haz eso con cada función que vayas a crear. Piensa en grande, es decir, piensa en que cada función tiene que hacer una cosa específica y de la mejor forma posible.

    Un truco es escribir el <main> de forma que se entienda a simple vista, por ejemplo:
    Código (cpp) [Seleccionar]

    int main(){
        fichero = abrirFichero();
        numero = leerNumero();
        if(esPrimo(numero))
            cout << numero << " es primo" << endl;
        else
            cout << numero << " no es primo" << endl;
    }

    Y en base a eso crear las funciones añadiendo los parámetros que veas que necesitas, poniendo los retornos que necesitas, etc.
    Tampoco te pases con las funciones, es decir, no empieces a meter una función dentro de otra y esta dentro de otra... Porque se hará demasiado lioso y no te valdrá la pena encapsular tanto. Tienes que encontrar el término medio. Piensa que una función es un trozo de código que puedes usar muchas veces en diferentes programas. Haz funciones que sean reutilizables.
    Por ejemplo, puedes pensar en hacer una función que te muestre por pantalla si un número es primo o no, pero... y si en algún momento quieres saber si el número es primo pero no quieres mostrarlo por pantalla? (como en tu ejercicio anterior). Pues mejor hacer una función que te diga si es primo o no, sin mostrar nada y tú verás en cada situación si quieres mostrar por pantalla el resultado obtenido o no.

    Comenta los avances que consigas empleando esta técnica y cuando pueda te seguiré ayudando. Suerte :-X
#552
Pon el código entre etiquetas de código GeSHi, sino no se ve la i entre corchetes...
Si en el <cout> del <for> estás poniendo la i entre corchetes después de la c, es decir:
Código (cpp) [Seleccionar]

cout << c[i];

No deberías de tener problemas. El código está bien. Puede ser porque lo hayas ejecutado antes y no hayas cerrado la ventana de ejecución. Prueba de nuevo y sino prueba a cerrar el IDE y volver a abrirlo y me cuentas.
(Estoy suponiendo que compilas con un IDE (netbeans, dev-c++, codeblocks,...) si no es así y estás compilando en línea de comandos (g++ programa.cpp -o programa) entonces pon la orden con la que estás compilando para poder ayudarte)
#553
Programación C/C++ / Re: Ayuda de c++.
20 Mayo 2019, 17:49 PM
Espero que sea una duda sobre un ejercicio y no sea el típico mensaje pidiendo un ejercicio hecho. Además el foro está para tratar los temas de forma abierta y que te puedan ayudar todos y si luego alguien quiere leerlo, también le podrá servir de ayuda...
#554
Citar
Buenas!
YreX-DwX no entiendo muy bien el pseudocódigo que me pones para EsPrimo:

para i := 2 hasta numero-1
    si numero % i == 0
        return false
    fin si
fin para
return numero >= 2

¿Me la podrías explicar un poco más porfa?
Acabo de ver que le di la vuelta a lo que es ser primo en esa función por lo que no es correcta, ahora te la corrijo (está corregida en la cita)
Un número es primo si solo es divisible por si mismo y la unidad (no se considera al 1 primo). Entonces en vez de contar los divisores desde 1 hasta n y comprobar si el número de divisores es 2 (es primo) o es >2 (no primo); lo que hacemos es evitar esas dos divisiones. En lugar de empezar en 1 hasta n, empezamos en 2 hasta n-1. De esta forma se define como número primo todo aquel número que no es divisible por ningún número entre 2 y n-1 (excepto el 2 que es divisible por 2 y es primo).
El 1, en cambio, no es primo y el bucle no llega a ejecutarse para números < 3. Entonces en caso de que el bucle no se ejecute (esto sucede si los números son 1 o 2) tenemos que el 1 no es primo y el 2 sí.
Para tratar esa excepción usaremos <return (numero >= 2)> (date cuenta de que es una expresión booleana cuyo valor siempre es true/false, no son asignaciones).
Funcionamiento:
Se ejecuta el bucle (para números > 2) y si encuentra un divisor devuelve <false> (fallo mío que puse <true> lo voy a corregir en los otros mensajes) .
Si no encuentra un divisor podemos tener 2 motivos:
  • El número es < 3: {0, 1, 2} en cuyo caso el único primo es el 2
  • El número es > 2 y es primo: {3, 5, 7, 11, ...}
    Entonces con la condición <return (numero >= 2)> obtendremos <true> (para el 2 y todos los primos) y <false> (para el 0 y el 1). Ahora sí está correcta la función y disculpas por el error... :-X


    Citar
    Y no me saca nada más que los dos primeros números perfectos usando los primos de Mersenne, o sea el 6 y el 28 nada mas ¿que es lo que tengo mal?
    Eso es porque estás usando la variable <perf> para guardar la cantidad de números perfectos que llevas y el número perfecto actual. Entonces en el momento que el número perfecto supera el 10 (28 en este caso) termina. Usa dos variables distintas, una para el número perfecto y otra para la cantidad de números perfectos que llevas.
#555
Supongo que estás empezando por tu duda y que por tanto no usas memoria dinámica. Entonces puedes hacer lo siguiente:

#define MAX_SIZE 100 // creamos un array/vector de capacidad maxima = 100

int main(){
    float notas[MAX_SIZE]; // creamos un array de 100 elementos
    int num_notas; // cantidad de notas que vamos a introducir. Tiene que ser menor o igual que el MAX_SIZE
    float promedio = 0; // promedio de las notas

    printf("Introduce el numero de notas que vas a almacenar: ");
    scanf("%d", &num_notas);

    for(int i = 0; i < num_notas; ++i){
        printf("Introduce la nota %d: ", i+1);
        scanf("%f", &notas[i]);
    }

    // si queremos calcular el promedio...
    for(int i = 0; i < num_notas; ++i)
        promedio += notas[i];
    promedio /= num_notas;
}

Así ya tienes todas tus notas guardadas en un array. Cuando lo vayas a recorrer recuerda recorrerlo hasta <num_notas>, no hasta <MAX_SIZE> ya que desde la posición notas[num_notas] hasta notas[MAX_SIZE-1] tendrás basura.

Si lo quieres solo para el promedio. Puedes hacerlo más simple.

int num_notas; // numero de notas que vamos a introducir
float nota; // guarda la nota actual
float promedio = 0; // acumula la suma de las notas y al final guarda el promedio
// preguntas la cantidad de notas a introducir
for(int i = 0; i < num_notas; ++i){
    printf("Introduce la nota %d: ", i+1);
    scanf("%f", &nota);
    promedio += nota; // equivalente a promedio = promedio + nota
}
promedio /= num_notas; // equivalente a promedio = promedio / num_notas


Citar
Tambien deberias agregar una variable que cuente las veces que se repite el cuerpo del for, no seria correcto usar la "i" en este caso por que siempre quedaria con 1+ de las veces que se repitio el cuerpo del for, a menos que le decrementes uno,una vez que termine el for.
Ya lo tiene agregado eso. En su caso es <vm> (aunque un nombre como <num_notas> es más específico)...
#556
EDITO: Se ha corregido el pseudocódigo para ver si un número es primo <return true> por <return false> y <return numero == 2> por <return numero >= 2>.

Citar
me equivoqué al expresarla, no quería decir una potencia de dos, sino una potencia de base 2.
Creo que sigue sin ser eso :xD. Creo que lo que quieres decir no es "una potencia de base 2 elevada a un número primo, menos 1, da como resultado otro número primo" sino que los números primos de Mersenne son los números primos que resultan de elevar un 2 a una potencia prima y restarle 1. Pero no todos cumplen tu suposición como he mostrado antes por ejemplo con el 11.

Citar
Luego en la función EsPrimo, he quitado los else como me dijiste, ya que es cierto lo que dices, no había caído. Y he aunque he añadido otro if con el 7 sigue sin ser correcta porque siempre me dará error al escribir múltiplos de los números primos, como es el caso del 11, 13... así que no tengo ni idea de como hacerlo, ya que de la forma que dice storing Manolo si que sé, pero en el ejercicio me piden que lo averigüe sin contar los divisores... ayuda!!
En lugar de empezar dividiendo por 1 (que siempre va a ser divisible) y terminar dividiendo por el propio número (que siempre va a ser divisible) y comprobar que para que sea primo se tiene que poder dividir exactamente por 2. Reduce las iteraciones innecesarias. Si el 1 siempre es divisible y el propio número también haz:

para i := 2 hasta numero-1
   si numero % i == 0
       return false
   fin si
fin para
return numero >= 2

Este pseudocódigo te sirve para una función que indica si el número es primo sin contar los divisores y teniendo en cuenta que el 2 es el primer primo.

Cita de: string Manolo en 17 Mayo 2019, 10:41 AM
La formula que está en main es la que saqué de wikipedia. Tenia un problema con los resultados que no coincidian, concretamente a partir del 3 numero primo que me daba 9 y en wikipedia me salia que era 31 cambie mi función Potencia por pow en el main para ver si implementara mal la funcion y todos los resultados coincidian, primos y perfectos. Entonces arreglé mi función Potencia y los resultados eran los mismos que con pow.
Respecto a esto, tenemos el desarrollo de la wikipedia: https://es.wikipedia.org/wiki/N%C3%BAmero_perfecto en la sección de "Son Números Triangulares".
Según lo que me dices de que tus resultados son los mismos, tenemos la siguiente tabla:

NP: Numeros primos
NPX: Numeros primos generadores de los numeros primos de Mersenne
NPerfecto: Numeros perfectos usando los NP
NPerfectoX: Numeros perfectos usando los NPx
NPerfectoO: Numeros perfectos originales

NP  NPX    NPerfecto                              NPerfectoX = NPerfectoO
2     2         6                                             6
3     3         28                                           28
5     5         496                                         496
7     7         8128                                       8128
11   13       2096128                                 33550306
13   17       33550306                               8589869056
17   19       8589869056                           137438691328
19   31       137438691328                       2305843008139952128
23   61       35184367894528                   2658455991569831744654692615953842176
29   89       144115187807420420           191561942608236107294793378084303638130997321548169216
#557
Dejando a un lado las respuestas que no llevan a nada productivo pero que puedo resumir en "enseñar malas prácticas a alguien que está empezando genera otra persona que enseñará malas prácticas a otros que estén empezando".
Citar
Por lo que entendí de la formula en wikipedia, cualquier numero primo al que se le aplique la formula pasa a ser automáticamente un numero primo de Mersenne sin necesidad de nada mas. De no ser así con volver a llamar a la función EsPrimo ya estaría el problema solucionado. Pero consulte la salida de los valores de la variable que almacena los numeros primos de Mersenne y coincidian con los que encontre en google. Estás seguro de que son incorrectos? Porque también comprobé los 10 numeros perfectos en google y eran los mismos que me da la salida de mi programa.
Los números primos de Mersenne son números que se calculan con la fórmula M(p) = 2^p-1 donde p es primo y M(p) también lo es. Si cogemos p = 11, tenemos M(11) = 2047 = 23 * 89, por lo que p sí es primo pero M(p), no. No había comprobado lo del número perfecto pero lo hacemos ahora. 2047 * 2^10 = 2096128 que se encuentra entre el tercer número perfecto (8128) y el cuarto (33550336), por lo que no es un número perfecto... al menos en donde yo he comprobado esos resultados que no digo que sea una página 100% fiable pero una de las dos, la tuya o la mía, es incorrecta.

#558
Cita de: string Manolo en 17 Mayo 2019, 08:07 AM
Vaia coñazo de trabajos os mandan hacer. No tengo ni zorra de mates, pero es solo seguir las pautas del ejercicio y preguntarle las formulas a wikipedia. Haciendo estos ejercicios no aprendes nada. Buscate un libro teorico de C++. Te recomiendo Apress Learn C++ Game Development 2014. Cuando lo acabes pasate por la web https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list y pilla el libro de 1000 hojas que es el asco teorico más grande. Ve haciendo programas que se te ocurran mientras vas asimilando conceptos.

No hagas copia y pega que si tu profesor busca en google el codigo le saldra este post xD
Código (cpp) [Seleccionar]

#include <iostream>
using namespace std;

unsigned long long Potencia (unsigned int Base, unsigned int Exponente)
{
unsigned long long potencia = 1;
int i;
if (Exponente==0) return 1; //Error.
else
{
for(i=0;i<Exponente;++i)
{
potencia*=Base;
}
}
return potencia;
}

bool EsPrimo (unsigned long long Numero)
{
int Contador = 0;
bool esPrimo = false;
for (int i=1;i<(Numero+1); ++i)
{
if(Numero%i==0)
{
++Contador;
}
}
if(Contador!=2)
{
//Mete un cout por aqui de Numero si quieres para ver el numero que no es primo.
return esPrimo;
}
else
{
esPrimo = true; //Mete un cout por aqui de Numero si quieres, para ver el numero que si es primo.
return esPrimo;
}
}

int main()
{
unsigned int Numero = 1; //Numero a comprobar si es primo.
unsigned int Contador = 1; //Contador para bucle do while.
unsigned long long NumeroPrimoM;
unsigned long long NumeroPerfecto;
do {
   if ( EsPrimo(Numero) ) //Funcion EsPrimo retorna true si el valor de Numero es primo.
   {
   NumeroPrimoM = Potencia(2,Numero) -1; //Formula para sacar primo de Mersenne.
//Mete un cout aqui de NumeroPrimoM si quieres conocer a los primos de Mersenne.
   NumeroPerfecto = (NumeroPrimoM*(NumeroPrimoM +1))/2; //Formula para sacar numero perfecto utilizando numero primo de Mersenne.
   cout << Contador << " - Numero Perfecto: " << NumeroPerfecto << endl;
   ++Contador; //Para el bucle while y seguir calculando hasta 10.
   ++Numero;//Probemos si el siguiente numero es primo.
       }

   else
   {
   ++Numero; //Si el valor en Numero no es primo, prueba el siguiente.
   }

} while (Contador != 11);
return 0;
}

Si no entiendes algo pregunta.

O sea estos trabajos que te ayudan a pensar de forma lógica y a saber implementar las ideas que tienes en la cabeza son un coñazo y leerte un libro de 1000 páginas que ya adelantas ser "el asco teórico más grande" es mejor para alguien que está empezando?? Será buena idea si lo que quieres es que abandone la programación por parecerle "un coñazo".

En esa función <Potencia()> si tomas el caso de que exponente valga 0 de forma aislada (y no es un error eso) no tienes que inicializar <potencia> a 1 sino a <base> (es más puedes usar la propia variable base que no está pasada por referencia ni es constante para ahorrarte una variable y una iteración). Tal y como está implementado ahí, el bucle funciona también para el exponente 0 por lo que no es necesario tratarlo de forma aislada.

La función <esPrimo()> aparte de hacer iteraciones de más de forma innecesaria usa una variable para guardar true/false antes de retornar cuando se puede retornar el valor directamente. Y el <else> tampoco es necesario.

Ese programa no calcula los primos de Mersenne, calcula los números de Mersenne (no aseguras en ninguna parte que sean primos, es más, no lo son) por lo que los resultados no son correctos tampoco.

Y el uso correcto del <do while> es para bloques que deben ejecutarse una vez antes de comprobar la condición siempre, lo cual no es el caso. Para este caso por convención se emplea un <while>.

Al final los trabajos "coñazo" van a servir para ver los fallos que comete uno.
#559
Bueno el problema principal como bien dices es que el operador < no está bien sobrecargado. Este operador pertenece a la clase, no es un operador externo a la clase que deba declararse como <friend>, es decir, sería así:
Código (cpp) [Seleccionar]

bool Usuario::operator<(const Usuario &otro)const{
    return strncmp(this->nombre, otro.nombre, size) < 0;
}

Esa función compara el número de caracteres indicados en <size> de ambas cadenas y retorna un valor negativo si la primera es menor a la segunda, un valor positivo si la primera es mayor a la segunda y 0 si son iguales.

Además de eso la declaración de <usuario> la puedes hacer una única vez antes de empezar el bucle y luego ir cambiando el valor de <nombre> en cada iteración.

Además no tiene mucho sentido usar arrays dinámicos si siempre los creas de tamaño 16, porque entonces... hasta dónde comparas las cadenas?? Tienes dos opciones:
  • Crear un array estático muy grande donde guardar el nombre introducido por el usuario, calcular los caracteres útiles y entonces reservar memoria justo para esos caracteres.
  • Usar string que es la ventaja de C++ para trabajar con cadenas de caracteres. Si usas string tendrás que convertirlos a char* para usar las funciones típicas de las cadenas pero eso se puede hacer simplemente con <nombre_string.c_str()>

    Aparte de eso, el <set> mejor que sea local en el <main> en lugar de global.
#560
Una cadena de texto <char*/char[]> es un arreglo unidimensional por lo que hacer un arreglo de cadenas de texto es un arreglo bidimensional. Tienes que imaginarlo como una matriz donde cada cadena se escribe en una fila y cada caracter en una columna.

Dicho esto para leer palabras de un fichero tienes la función <fgets()> en C. Esta función tiene la siguiente forma:

char *fgets(char *variable, int max_size, FILE *fichero)

El valor de retorno no importa mucho ya que retorna lo mismo que guarda en <variable>.

Donde <variable> es el arreglo en el que vas a guardar lo que lees, <max_size> la cantidad máxima de caracteres que va a leer la función y <fichero> pues el fichero de donde lo va a leer. La función lee hasta que encuentra un salto de línea o hasta llegar al máximo indicado (lo que antes ocurra). Con el segundo parámetro te aseguras de que no tienes problemas de memoria. Si usas un arreglo estático, usa el tamaño del arreglo como segundo parámetro de la función <fgets()>.