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

#91
Para futuras consultas, el código debe ir entre etiquetas de Código GeSHi. Puedes seleccionarlas desde un desplegable que hay encima del cuadro de texto que dice "Código GeSHi" donde puedes elegir tu lenguaje de programación o escribiendo directamente:
[code=cpp]
Tu código aquí
[/code]



El problema es el cálculo que estás haciendo. Piensa que i va desde m hasta n entonces tienes que ir comprobando si cada i es primo o no y no es eso lo que haces. Para ello tendrías que hacer otro bucle dentro de ese que vaya desde 1 hasta i y comprobar ahí cuántos divisores tiene.
Código (cpp) [Seleccionar]

for(int i = m; i <= n; ++i) {
  for(int j = 1; j <= i; ++j) {
    // aqui compruebas la divisibilidad
  }
}


Este código no es el más eficiente pero es el mejor para empezar ya que se ve claramente lo que estás haciendo. Cuando consigas que te funcione puedes intentar mejorarlo poco a poco o comentarlo aquí.

Suerte  :-X
#92
Java / Re: remove no funciona
18 Marzo 2021, 07:10 AM
Supongo que <cartasEnMano> es un ArrayList<> de algún tipo de objeto que has creado tú, no?

Cuando se utiliza ArrayList.remove(Object o), se elimina el objeto i del array que cumpla Objects.equals(o, array.get(i)). En resumen, necesitas sobreescribir el método equals() para determinar cuándo dos objetos son iguales ya que si no lo haces sólo serán iguales cuando sean el mismo objeto (misma dirección de memoria).

Otra solución más sencilla si ya tienes el índice es usar ArrayList.remove(int index).
Código (java) [Seleccionar]
j.cartasEnMano.remove(op)
Además de más sencillo, es más seguro pues te aseguras de tirar exactamente la misma y no otra que sea igual a esa.


PD: Utiliza las etiquetas de Código GeSHi para el código ya sea abriendo el desplegable que se llama "Código GeSHi" y eligiendo Java o escribiendo directamente:
[code=java]
Tu código Java aquí
[/code]
#93
Pues como ya ves, estás poniendo en la primera línea del main() la ruta de la carpeta mediante un String. Lo único que tendrías que hacer es solicitar al usuario ese String en vez de ponerlo por defecto y sería bueno comprobar que la ruta existe mediante los métodos de la clase File.

Una opción más visual para un usuario final es usar un JFileChooser para hacer la típica ventana que te permite elegir un fichero/directorio. En Internet hay ejemplos de cómo usarlo.
#94
Bueno pues a ver... Varias cosas a mencionar:
  • Pongo esto lo primero porque creo que es el error más básico de todos: El código me hace sospechar que tienes un problema con el ámbito de las variables. La pila que creas en la línea 24, la utilizas únicamente en la 115 además de forma muy extraña.
    Cuando en una función estableces el nombre de una variable, puede ser cualquiera. Este nombre solo sirve dentro de la función y realmente se corresponde con el argumento que hayas pasado al llamar a la función. Ver la función mostrarPila() más adelante...
  • La función Pilas_1() no es muy descriptiva. Sería mejor algo como push(p1, dato) simulando las funciones típicas de una pila (push, top, pop)
  • No tiene sentido hacer una función para mostrar una pila y otra para mostrar otra pila. La gracia es tener una única función y mediante parámetros decirle qué pila mostrar en cada momento.
  • Además si mueves el puntero, pierdes la referencia al inicio de la pila. Tienes que crear un puntero auxiliar.
    Código (cpp) [Seleccionar]

    void mostrarPila(Nodo *&p) {
      Nodo *aux = p;
      while(aux != NULL) { // En C++ para punteros no se debe usar NULL sino nullptr
        cout << aux->dato << " ";
        aux = aux->sig;
      }
    }
    // Para mostrar las pilas 1 y 2:
    mostrarPila(p1); // Aqui la variable p que se usa en la funcion hace referencia a p1
    mostrarPila(p2); // Ahora la misma variable p hace referencia a p2



    Yendo al grano ahora, la función para fusionar pilas deberías ser algo así:
    Código (cpp) [Seleccionar]

    void fusionarPilas(Nodo *&p1, Nodo *&p2, Nodo *&fusion) {
      // Recorres p1 como si fueras a mostrarla pero en vez de mostrarla vas guardando cada elemento en fusion...
      // Tu codigo aqui
      // Recorres p2 como si fueras a mostrarla pero en vez de mostrarla vas guardando cada elemento en fusion...
      // Tu codigo aqui
    }
    // Para llamar a la funcion:
    fusionarPilas(p1, p2, pila); // La fusion se guardara en la pila <pila> de la linea 24

    Es mejor hacerlo así para no modificar las pilas originales y guardar la fusion en otra diferente.
    Si completas este código correctamente, debería funcionar y para comprobarlo ya sabes:
    Código (cpp) [Seleccionar]
    mostrarPila(pila);

    Además fíjate que en tu función creas un nodo nuevo (línea 109) y luego apuntas a p1. Ese nodo nuevo se pierde, no sirve para nada.
    PD: Estás trabajando con memoria dinámica (al utilizar new). Por tanto, antes de acabar el programa, debes eliminar toda esa memoria reservada mediante delete (nodo a nodo).

    PD2: No es recomendable utilizar system("pause"). La mejor alternativa en C++ es utilizar cin.get() para el mismo propósito.

    PD3: Las bibliotecas en C++ no llevan .h y en cambio llevan una c al principio: stdlib.h (versión C) -> cstdlib (versión C++) Funciona de todas formas por la compatibilidad con C pero no es lo más correcto.
#95
Al igual que en el tema anterior, el código debe incluirse entre etiquetas de Código GeSHi


Si no quieres tener en cuenta el 0, es muy sencillo.
Código (cpp) [Seleccionar]

int numero = -1;
for(int i = 0; i < MAX_NUM && numero != 0; ++i) {
  cout << "Introduce un numero: ";
  cin >> numero;
  if(numero != 0) {
    // todo lo demas
  }
}



Otra forma de conseguir lo mismo sería:
Código (cpp) [Seleccionar]

int numero;
cout << "Introduce un numero (0 para terminar): ";
cin >> numero;
while(numerosIngresados < MAX_NUMEROS && numero != 0) {
  ++numerosIngresados;
  // comprobar si es par/impar y positivo/negativo
  cout << "Introduce otro numero (0 para terminar): ";
  cin >> numero;
}

Personalmente me gusta más la segunda opción. Queda un código un poco más limpio, evitas el uso de una variable más, no necesitas inicializar <numero> a un valor concreto para que funcione y puedes cambiar el mensaje para que ponga "...otro número..." en vez de siempre "...un número...".
Además en muchas ocasiones (sobre todo académicas) se suele incidir en utilizar un for() únicamente cuando la condición dependa solo del contador del for() y no con condiciones compuestas (aunque sea totalmente válido); y por ende sustituirlo por un while() en tal caso.
#96
Antes que nada, el código debe publicarse siempre mediante etiquetas de Código GeSHi. Puedes seleccionarlas en el desplegable que dice "Código GeSHi" encima del cuadro de texto o escribiendo directamente:
[code=cpp]
<Tu código aquí>
[/code]


El problema viene a raíz de que la condición de <n != 0> no está contemplada en el for(). Entonces el for() no va a terminar hasta que se ingresen 5 datos.
De todas formas, un bucle dentro de otro no es la forma más apropiada de hacer esto. Debes usar dos condiciones juntas mediante un operador lógico (AND && o OR ||).

Es mejor utilizar constantes para los límites y que así se pueda modificar rápidamente y sin errores.
Código (cpp) [Seleccionar]

const int MAX_NUMEROS = 100;

int main() {
  int numero = -1; // Ponemos un valor por defecto distinto de 0 para que el for() funcione
  for(int i = 0; i < MAX_NUMEROS && numero != 0; ++i) {
    // Aqui haces todo lo que tengas que hacer
  }
}


Tienes dos opciones:
  • Guardar todos los valores en un array y una vez ingresados todos, calcular lo que se pide.
  • Realizar los cálculos después de pedir cada número. No es necesario usar arrays.
    Inténtalo de la forma que quieras y si necesitas ayuda puedes pedirla añadiendo tus avances para poder ayudarte mejor.

    Suerte  :-X
#97
Java / Re: Mejorar Captura Firma Manuscrita
23 Febrero 2021, 01:14 AM
@Slf4j es una anotación que permite generar un log de forma alternativa a crear un atributo static. Para utilizarlo debes incorporar la biblioteca lombok a tu proyecto e importarlo con:
Citar
Código (java) [Seleccionar]
import lombok.extern.slf4j.Slf4j;

Los logs sirven para producir mensajes en determinados puntos y mostrarlos o guardarlos en un fichero de salida (lo que se conocen como los logs de la aplicación) para ver un seguimiento y poder detectar errores, problemas,...

Si no vas a utilizar logs en tu aplicación y/o no utilizas lombok, puedes eliminar esa anotación y el import indicado antes sin problemas y todo debería funcionar correctamente.

Suerte  :-X
#98
Antes de nada, el código debe estar publicado entre etiquetas de Código GeSHi. Puedes seleccionarlas en el desplegable que dice "Código GeSHi" (encima del cuadro de texto) o escribiendo manualmente:
[code=java]
<tu código aquí>
[/code]


Esto es por el siguiente bloque:
Citar
Código (java) [Seleccionar]

do {
   if ((resultado >= intMin) && (resultado<=intMax)){
       textCalcu.setText(Integer.toString(num));
   }
   num++;
} while ((num * num >= intMin) && (num * num <= intMax));
Estás cargando en textCalcu el valor del primero, en la siguiente iteración lo sustituyes por elsegundo y así sucesivamente. Entonces no te da tiempo a verlos y únicamente ves el último que es el que queda indefinidamente.
Por otro lado veo un error importante y es que no estás actualizando el valor de resultado (siempre vale 0).
Por último, la estructura do-while() no es la más adecuada para esta situación. Lo correcto sería utilizar un while() o en su defecto un for() ahorrando la condición del if().

La forma de hacer esto es crear un String auxiliar en el que ir concatenando toda la cadena que quieres mostrar. Por ejemplo:
Código (java) [Seleccionar]

String mensaje = ""; // Importante inicializarlo para poder concatenar
int num = 0;
while(num * num >= intMin && num * num <= intMax) {
   mensaje += num + " - "; // El " - " es para separarlos mediante un guion, puedes usar "\n" para separarlos por lineas
   ++num;
}
// Y una vez creada la cadena completa, la muestras:
textCalcu.setText(mensaje);

Como ves, no utilizo la variable 'resultado'. La puedes utilizar para guardar la operación de (num * num) y no tener que calcularla 2 veces.
Otra posible mejora es utilizar un StringBuffer o StringBuilder en vez de String para concatenar la cadena (es más eficiente).


Otra posible solución para no tener que multiplicar (num * num) en cada iteración, es hacer la operación inversa. Es decir si tiene que cumplirse que:
intMin <= (num * num) <= intMax
Entonces también tiene que cumplirse:
sqrt(intMin) <= num <= sqrt(intMax)
siendo sqrt(n) la raíz cuadrada de n.
Sin embargo, en esta ocasión tendrías que tener cuidado para comparar entre números enteros y números reales.
#99
Antes de nada, el código debe publicarse entre etiquetas de Código GeSHi para facilitar su lectura. Puedes seleccionar las etiquetas mediante el deplegable que dice "Código GeSHi", encima del cuadro de texto o escribiendo manualmente:
[code=cpp]
Aquí escribes tu código
[/code]


Todos tuvimos nuestros inicios y todos nos hemos hecho preguntas y hemos tenido problemas con cosas que luego se vuelven muy básicas.   :-X

El problema es que estás definiendo una función: product() dentro de otra función: main(). Existe la posibilidad de hacer esto de varias formas pero no es nada recomendable. Lo suyo es definir las funciones fuera de otras funciones.
Además hay 2 formas de hacerlo:
  • Implementar la función antes de utilizarla:
    Código (cpp) [Seleccionar]

    #include <iostream>
    using namespace std;

    void saludar() {
     cout << "Hola" << endl;
    }

    int main() {
     saludar(); // La salida sera: Hola
     return 0;
    }


  • Definir la función antes e implementarla después. Para programas muy pequeños parece innecesario pero para códigos grandes te evitará muchos dolores de cabeza (ya lo irás viendo):
    Código (cpp) [Seleccionar]

    #include <iostream>
    using namespace std;

    void saludar(); // Escribes la definicion de la funcion (valor de retorno, nombre de la funcion y parametros)

    int main() {
     saludar();
    }

    // Implementas la funcion que has definido antes
    void saludar() {
     cout << "Hola" << endl;
    }





    Además como un par de consejos más de inicio:
  • Está bien ir conociendo para qué sirve cada biblioteca (las cabeceras) y así usar sólo las necesarias. La cabecera <iostream> es la que contiene todo lo necesario para la entrada/salida estándar de C++ (cout, cin,...) mientras que <stdio.h> es la cabecera de entrada/salida propia de C (printf, scanf,...). Las funciones min() y max() que utilizas se encuentran concretamente en la cabecera <algorithm> aunque bajo mi punto de vista sería mejor que crearás tus propias funciones para mejorar tu lógica y ganar experiencia, sobre todo al principio.
  • Las cabeceras que terminan en '.h' son propias de C. Estas también funcionarán en C++ pero puedes usar su propia versión cuyo nombre es igual pero eliminando el '.h' del final y añadiendo una 'c' al principio. <stdio.h> (C) -> <cstdio> (C++)
  • Aunque se puede hacer, no se recomienda crear la función main() sin un tipo de retorno. Esta función en C++ (y en C también) devuelve un int. Por convención se suele devolver 0 si todo va bien y otro número (1, -1,...) si algo falla. Lo escribas o no, el compilador añadirá un 'return 0;' al final de la función main() siempre.

    Te dejo un par de enlaces bastante buenos para conocer funciones, saber qué cabeceras necesitas y cómo funcionan:
    http://www.cplusplus.com/
    https://en.cppreference.com/w/

    Es bastante información para ya irás aprendiendo poco a poco según vayas avanzando y practicando. En programación da igual cuánto estudies si no practicas. Suerte  :-X



    EDIT: Y ahora que me doy cuenta, tu función product() devuelve un int según lo has definido pero te falta añadir un 'return' al final. Te dará un error si no lo pones.
#100
Java / Re: Arreglos Bidimensionales
9 Febrero 2021, 15:50 PM
Lo primero y más importante: el código debe ir siempre entre etiquetas de Código GeSHi y a ser posible para el lenguaje apropiado y correctamente indentado. En tu caso deberías escribir:
[code=java]
Aqui escribes tu código
[/code]

Ahora antes de comentar el problema, voy a comentar la descripción de este:
Citar
Diseñar un programa que ingrese números enteros a un arreglo bidimensional. Se pide calcular e imprimir el segundo número capicúa más alto de cada diagonal principal del arreglo (cuando M = N). No usar arreglo lineal.
Problemas con esa descripción (para la parte en negrita concretamente):
1 - ¿Qué se entiende por diagonal principal? Si se entiende por diagonal principal únicamente la que empieza en la posición (0,0) y continúa por (1,1), (2,2),...(n,n); únicamente existe una diagonal principal en cada matriz cuadrada por lo que eso de "CADA diagonal" confunde un poco.
Si por el contrario, se refiere a todas las diagonales menores que son paralelas a la diagonal principal, entonces tu programa tiene otro problema y es que sólo evalúas la diagonal principal mayor.
2 - "Cuando M = N"... Si es una aclaración de lo que es la diagonal principal, entonces sólo existe una y el "CADA diagonal" estaría fuera de lugar. Otra interpretación es que el programa sólo analice las matrices cuadradas, es decir, que haga todo lo que se pide únicamente cuando M sea igual a N.

Para no complicarme supondré una única diagonal principal por matriz ya sea ésta última cuadrada o no.

Ahora yendo al problema principal, no entiendo qué hace tu método diagonales() que muestro a continuación y que he ido añadiendo comentarios en todo aquello que tenía que comentar:
Código (java) [Seleccionar]

public static void diagonales(){
    // Si solo vas a recorrer la diagonal principal basta con hacer un for(int i = 0; i < menor(m,n); i++) y utilizar num[i][i]
    for(int i=0; i<m;i++){
        for(int k=0; k<n;k++){
            if(i==k){
                CapicuaNumero=0;
                auxMayor=0;
                auxCapicuaPrincipal=num[i][k];
                // Aqui empiezas a quitar el ultimo digito al numero pero...
                while(auxCapicuaPrincipal>0){
                    cifra = auxCapicuaPrincipal%10;
                    auxCapicuaPrincipal=auxCapicuaPrincipal/10;
                    //CapicuaNumero = 0
                    NumeroPrincipal=(CapicuaNumero*10)+cifra; // ...CapicuaNumero siempre vale 0, asi que eso siempre es = cifra
                }
                if(NumeroPrincipal==num[i][k]){
                    if(NumeroPrincipal>auxMayor){ // Aqui auxMayor siempre es 0
                        NumeroP = respuestaPrincipal; // Aqui respuestaPrincipal no tiene valor asi que es 0
                    }
                }
                System.out.println("numero capicua"+NumeroP);
            }
            /*if((i+k)==num.length-1){
                auxCapicuaSecundario=num[i][k];
            }*/
        }
    }
    JOptionPane.showMessageDialog(null,"El mas alto numero es "+NumeroP);
}


Además de los errores, tu código necesita mucha más organización de la que tiene. Muchos de los atributos de la clase no son necesarios y bastaría con utilizar variables locales a su método. Además la asignación de valores a no ser que sean constantes, es mejor que lo dejes para el main() o cualquier otro método y no lo incluyas en la misma declaración de los atributos.
Y como recomendación, crea un método que sea esCapicua(int) y que devuelva true/false según si el número indicado es capicúa o no. Esto te facilitará mucho el trabajo.
Código (java) [Seleccionar]

public class Principal {
  private static int numFilas;
  private static int numCols;
  private static int[][] matriz;

  public static void main(String[] args) {
    numFilas = Integer.parseInt(...);
    numCols = Integer.parseInt(...);
    matriz = new int [numFilas][numCols];

    rellenarMatriz();
    System.out.println("----- MATRIZ RESULTANTE -----");
    mostrarMatriz();

    int[] capicuasMayores = calcularCapicuasMayores(); // Puedes devolver los dos capicuas mas grandes
    System.out.println("El segundo numero capicua mas grande es: " + capicuasMayores[1]);
  }

  private static int[] calcularCapicuasMayores() {
    int capicuas[] = new int[2]; // En capicuas[0] se guarda el mayor y en capicuas[1] el segundo mayor
    boolean primerCapicua = true; // Flag para saber si es el primer capicua que guardamos. Si es negativo no vale comparar con > 0
    int dimensionMenor = numFilas < numCols ? numFilas : numCols;
    int numeroActual;
    for(int i = 0; i < dimensionMenor; ++i) {
      numeroActual = matriz[i][i];
      if(esCapicua(numeroActual)) { 
        if(primerCapicua) {               
          capicuas[0] = numeroActual;
          primerCapicua = false;                           
        } else if(numeroActual > capicuas[0]) {
          capicuas[1] = capicuas[0];
          capicuas[0] = numeroActual;
        } else if(numeroActual > capicuas[1]) {
          capicuas[1] = numeroActual;
        }
    }
    return capicuas;
  }

  private static boolean esCapicua(int num) {
    // Esto te toca a ti ya...
    // Si haces que esto devuelva true cuando un numero es capicua y false cuando no, todo funcionara correctamente (creo)
  }
}


Como ves, es un código organizado en métodos pero que cada uno hace una parte muy concreta y con solo mirar el método main() ya tienes una idea de lo que el programa hace, aunque no sepas cómo lo hace (para eso tendrías que mirar el resto de métodos).