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

#311
No he mirado todo tu código, solo la última parte pero... Deberías no cerrar el archivo dentro del while().
Saca el:
Código (cpp) [Seleccionar]
archivo.close();
fuera del while() de esta manera:
Código (cpp) [Seleccionar]

while(aux != NULL){
  archivo << aux;
  aux = aux->sigue;
}
archivo.close();

y dime si te funcionó.
#312
Cita de: dijsktra en  1 Mayo 2020, 21:38 PM
Hmmm.... Correcta!   ;-) ;-) ;-)

Una objección:

  •  La tecnica es estructurada, pero emplea 3 variables... trinangular_superior es redundante...

Se puede conseguir una solucion estructurada y con solo 2 variables locales?
Cuando tienes proyectos sin terminar pero @dijsktra te pica a darle más vueltas a un algoritmo aparentemente sencillo.  :laugh: :laugh:

Pues veamos. La primera opción que aparece es sustituir la variable por el valor de su expresión directamente que es:
A[i][j] == 0
dejando el resto del código lo más parecido posible. La solución en tal caso sería algo así:

int upperTriangleDesc(const int **A, const int N){
    size_t i = 1; j = 0; // Declaramos e inicializamos j para poder usarlo en la condicion del bucle externo
    while(i < N && !A[i][j]){
        // El bucle interno no tiene ninguna complicacion
        while(j < i && !A[i][j]){
            ++j;
        }
        // Ahora al salir tenemos dos situaciones:
        // - (j = i) y en tal caso la matriz todavia es triangular superior -> Incrementamos i y restablecemos j a 0 para recorrer otra fila
        // - (A[i][j] != 0) y en tal caso la matriz ya no es triangular superior -> No podemos modificar i ni j para que el bucle de fuera tambien termine
        if(j == i){
            ++i;
            j = 0;
        }
    }
    // Los bucles acaban cuando:
    // Un elemento no es nulo (A[i][j] != 0) -> !triangular
    // Llegamos al final (i == N) -> SI A[N-1][N-2] == 0 ENTONCES triangular SINO !triangular
    return (i == N && !A[N-1][N-2]);
}


Podemos ver que esto se complica mucho y solo para quitar una variable local. Así que tenía que haber otra solución. Existe otro patrón. Cada vez que salimos del bucle interno:
  • Todos los elementos de la fila son nulos -> j = i -> triangular (de momento)
  • El último elemento comprobado no era nulo -> j < i
    En vez de restablecer j a 0, podemos darle a j el valor del último elemento evaluado. Y en el bucle externo bastará comprobar si (j == 0). Esto tiene un problema: si todos los elementos evaluados en una fila son nulos -> j = i -> A(i,j) pertenece a la diagonal principal. Solución:

    int upperTriangleDesc(const int **A, const int N){
        size_t i = 1, j = 0;
        while(i < N && !j){
            while(j < i && !A[i][j]){
                ++j;
            }
            // Al salir: SI j < i ENTONCES A[i][j] != 0 SINO SI A[i][j-1] == 0 ENTONCES triangular (de momento) SINO !triangular
            j = (j < i) || A[i][j-1];
            ++i;
        }
        // Triangular <-> j = 0
        return !j;
    }


    A ver qué tal esta vez.  :silbar: :silbar:
#313
Como ya se ha explicado en el enunciado, una matriz es triangular superior descendiente si todos los elementos por debajo de la diagonal principal son nulos, es decir, 0. Por lo tanto el algoritmo debe recorrer única y exclusivamente esta parte de la matriz. El patrón es el siguiente:
  • Se empieza en la fila 1
  • Para cada fila i se recorren las columnas desde 0 hasta i-1.

    Por lo tanto la solución más sencilla parece un par de bucles que recorran esta parte de la matriz. Usaremos una variable entera como flag que empezará valiendo 1 (suponemos que la matriz es triangular superior) y cuando encontremos un elemento distinto de 0, dejará de ser triangular superior (cambiaremos el valor a 0) y no será necesario seguir.

    int upperTriangleDesc(const int **A, const int N){
    int triangular_superior = 1;
    for(size_t i = 1; i < N && triangular_superior; ++i)
    for(size_t j = 0; j < i && triangular_superior; ++j)
    triangular_superior = (A[i][j] == 0);
    return triangular_superior;
    }

    Usamos directamente la comparación de que el elemento (i,j) sea igual a 0. Si dicha comparación es cierta (true) se traducirá como un 1 y en caso de que sea falsa (false), se traducirá como 0.
    Como echo de menos estas cosas de C/C++ desde que trabajo con Java :rolleyes:
#314
Ya que eres nuevo en el foro, te avisaré de que no se hacen tareas. Esto no va de que tu pones tus códigos o tus ejercicios y nosotros te los hacemos. El foro sirve para cuando tienes una duda concreta y a ser posible tienes que poner tus avances para que podamos orientarte mejor.
Java como ya sabrás o deberías saber está totalmente orientado a objetos por lo que es obligatorio crear una clase para tu programa. C, en cambio, no está orientado a objetos (no tiene clases) aunque tiene un "apaño" que son la estructuras (struct). No conviertas cada clase de Java en un struct de C porque no tiene sentido, vas a tener que pensar un poco si deberías crearla o no.
PD: Otra característica de un struct es que todos sus campos son públicos por defecto. No se pueden establecer como privados.

Y para crear un número aleatorio en C se utiliza el siguiente código:

#include <stdlib.h> // Para las funciones rand() y srand()
#include <time.h> // Para la funcion time()

int main(){
  // Se establece una semilla que es como un generador de numeros aleatorios.
  // Una semilla con un valor x siempre genera los mismos numeros aleatorios en cada ejecucion.
  // Para que sea mas aleatorio se usa time(NULL) para usar la hora del sistema y que cambie con cada ejecucion.
  srand(time(NULL));

  int numeroAleatorio = rand();
  // El numero aleatorio esta entre 0 y la constante RAND_MAX.
  printf("Numero aleatorio entre %d y %d: %d", 0, RAND_MAX, numeroAleatorio);

  // Para obtener un numero entre [a, b):
  numeroAleatorio = a + rand() % (b-a);

  // Para obtener un numero entre [a, b]:
  numeroAleatorio = a + rand() % (b-a+1);
}


Dicho esto que creo que es lo más diferente entre Java y C, el resto son bucles y operaciones aritméticas básicas que tienes que poder hacerlo tú solo.
Suerte.
#315
Yo lo estaba ejecutando con Java 11 y desde Eclipse.
He probado a ejecutarlo directamente desde la consola y con Java 8 y el tamaño se reduce por debajo de 200.
No sabía yo que iba a haber tantos misterios en una cosa como esta.
#316
Estaba haciendo unas ventanas en Java cuando me dio por comprobar si realmente el tamaño de éstas se correspondía con el tamaño que había definido en el código fuente y he visto que no es así, no coinciden las medidas.
He estado leyendo sobre las dimensiones del JFrame (heredadas de Window), las dimensiones del Layout (que he probado también a usar diferentes tipos incluso null), los métodos set y get de height, width, minimumSize, preferredSize, bounds,... y todo lo que he ido encontrando por el camino; y no consigo unas conclusiones.

Os dejo un pequeño código de lo último que he probado y los resultados obtenidos:
Código (java) [Seleccionar]

public class App {
  private Ventana miVentana;

  public static void main(String[] args){
    miVentana = new Ventana();
    miVentana.setSize(200, 200);
    miVentana.setVisible(true);
  }
}

class Ventana extends JFrame {
  public Ventana(){
    getContentPane().setLayout(null);
  }
}


Establezco el layout a null para evitar que el layout pueda influir en las medidas de la ventana. Le doy un tamaño de 200 x 200 (que no choca con el tamaño mínimo de la ventana) pero al mostrar la ventana esta mide:
  • 234 x 242 (contando la barra de título)
  • 232 x 203 (contando el espacio interior de la ventana. Sin contar barra de título ni bordes)

    He probado también a usar el método setBounds() para establecer la posición de la esquina superior izquierda en las coordenadas (0,0), es decir, que la ventana debería aparecer pegada también a la esquina superior izquierda, pero realmente tampoco es así. En el eje X se desplaza 8 píxeles a la derecha, es decir, que la esquina superior izquierda de la ventana aparece en las coordenadas (8,0).
    Código (java) [Seleccionar]

    // Sustituir el setSize(200, 200) del codigo anterior por:
    miVentana.setBounds(0, 0, 200, 200);


    Sé que es un tema muy quisquilloso pero no sé de qué sirve poder establecer tamaños a las ventanas si luego no van a ser reales...
#317
Recoloca el código para que quede entre las dos etiquetas de code. No hay forma de ver bien tu código...

Para mostrar la N solo tienes que rellenar la primera y última columna de la matriz con asteriscos y la diagonal principal que ya te adelanté en el otro tema cómo hacerlo.
Código (cpp) [Seleccionar]

// Rellenar primera columna. Para la ultima columna es igual cambiando el 0 del corchete por (size-1).
for(int i = 0; i < size; ++i){
  matriz[i][0] = '*';
}

// Rellenar diagonal principal
for(int i = 0; i < size; ++i){
  matriz[i][i] = '*';
}


No entiendo por qué tanto bucle for() y por qué cambias los valores del contador del for() dentro de éste...
#318
Cita de: itzg3 en 27 Abril 2020, 19:01 PM
Entiendo la idea, muchas gracias.
Y si seria el caso de que tanto el administrador como el medico son personas diferentes, lo ideal seria el diagrama de la versión 01?
Aún estaría con una duda, es que mayormente en todo los sistemas de gestión un Administrador tiene acceso a toda las funciones del sistema. Pero desde mi punto de vista en este caso lo mas apropiado para el Administrador ¿seria solo el de gestionar a los usuarios del sistema, dejando el resto de módulos según corresponda al medico y asistente respectivamente?
(Esto se puede ver en la primera imagen).
Más que que sean personas diferentes, sería el mismo criterio de antes. Dependería de si el sistema necesita que el administrador cambie de rol para hacer una tarea del médico (diagrama 1) o por ser administrador puede hacer cualquier cosa que hace el médico (diagrama 2).
Al final que el administrador pueda hacer todo lo que corresponde al médico, no significa que lo haga, simplemente que el sistema no le pondrá pegas si en un momento determinado lo hace.

Ya te digo que no sé cómo funciona de forma real porque yo lo he visto de forma teórica y de la teoría a la práctica hay un trecho. Pero digo yo que en una empresa, si el jefe (pongamos un tío que dirige 1000 talleres de coches y va siempre con traje y maletín) quiere un día ponerse a cambiar una rueda no será el ordenador el que le diga "chsss tú, que no te dejo que trabajes cambiando ruedas, tú a tu despacho a hacer papeles que es lo que tienes que hacer".
O vamos puede que sí, que el registro de empleados se lleve de otra forma aislada y el jefe no pueda hacer las tareas de los empleados.
El ejemplo es un poco tremendista pero vamos es para que se entienda. Lo que diseñes es lo que el sistema va a permitir o a prohibir.

Con el segundo diseño, el jefe podría hacer el cambio de ruedas y poner en el sistema que el cambio de ruedas lo ha hecho él con su usuario de jefe y con el primero el jefe tendría que tener dos usuarios en el sistema: uno de jefe y otro de mecánico (que son los únicos a los que el sistema permite hacer un cambio de ruedas) y el sistema guardaría el usuario del jefe como mecánico y no como jefe.

Yo es como lo veo llevando la teoría a la práctica pero si alguien sabe cómo funciona realmente esto en el día a día seguramente pueda responderte con más precisión.

#319
Para el segundo diagrama en el que el administrador es a su vez médico y por tanto actúa en todos los casos de uso del médico, sería mejor usar la especialización. Si mal no recuerdo se representa con una flecha de un actor al otro para decir que uno "hereda" del otro.

Yo creo que el primer diagrama te valdría más si el sistema va a hacer distinción entre si la persona en un momento exacto tiene el rol de administrador o de médico. Entonces tendrías que tener una forma de saber si ese administrador está trabajando como médico o como administrador.
Y el segundo supuesto sería más correcto si el administrador puede hacer una labores u otras en cualquier momento sin tener que identificarse como administrador o como médico en cada momento. Pero como te digo haciendo una especialización entre el administrador y el médico para no repetir las flechas y hacer el diagrama más fácil de ampliar. (Así si añades un nuevo caso de uso para el médico, automáticamente lo tendrá disponible el administrador también).

Espero que te sirva la respuesta. La verdad es que es un tema que tengo un poco olvidado de cuando lo vi en la carrera. :rolleyes:
#320
No se hacen tareas. Sé más específico tanto con lo que se pide como con cuál es tu duda.
Si quieres recibir ayuda vas a tener que cambiar la pregunta y poner lo que lleves hecho (entre etiquetas de Código GeSHi).



EDIT: Bueno pues lo que tienes que hacer es crear una matriz (tabla) y en cada celda ir poniendo un asterisco o dejarla vacía para que al mostrar la matriz se vea cada una de las letras. La forma más fácil es usar una matriz cuadrada y rellenar partes de la matriz por separado. (También puedes encontrar un patrón y hacer la matriz en un único bucle pero me parece más complicado para empezar).
Supongo también que no has llegado al paso de matrices por parámetros así que lo haré todo en el main. Ya digo y repito que no es la mejor solución pero es fácil de ver.
Código (cpp) [Seleccionar]

#include <iostream>
using namespace std;

const int SIZE = 5; // Constante para las filas y columnas de la matriz. Mejor que sea impar para tener una fila y columna media

int main(){
  char matriz[SIZE][SIZE];

  // Voy a definir constantes para la E:
  int alto = SIZE; // De alto que ocupe toda la matriz (5)
  int ancho = SIZE; // La parte horizontal de arriba y abajo tambien (5)
  int anchoMedio = SIZE / 2 + 1; // Y la barra del medio: la mitad + 1 (3)

  // Rellenar la fila de arriba (0). Para rellenar la fila de abajo es igual cambiando el 0 por (alto-1).
  for(int i = 0; i < ancho; ++i){
    matriz[0][i] = '*';
  }

  // Rellenar el alto
  for(int i = 0; i < alto; ++i){
    matriz[i][0] = '*';
  }

  // Rellenar la barra del medio
  for(int i = 0; i < anchoMedio; ++i){
    matriz[alto/2+1][i] = '*'; // El +1 es para obtener la fila media de una matriz impar.
  }
}


Para mostrar una matriz:
Código (cpp) [Seleccionar]

for(int i = 0; i < filas; ++i){
  for(int j = 0; j < columnas; ++j){
    cout << matriz[i][j] << " ";
  }
  cout << endl;
}

Tendrás que sustituir <filas> y <columnas> por el nombre de tus variables.

Diciéndote cómo se hace la E, puedes hacer perfectamente la T. Y para la N te dejo como pista que puedes rellenar la diagonal principal de una matriz con:
Código (cpp) [Seleccionar]

for(int i = 0; i < size; ++i){
  matriz[i][i] = '*';
}


Luego ya que se vea mejor o peor dependerá de los tamaños elegidos y la forma que se le de a la letra.