Voy a pegarle un cabezazo al teclado.

Idontknow

Eso es lo que muchos haríamos cuando estamos hasta los cojones que no veamos la solución de un programa

Introducción.

Primer de todo tengo que decir que nunca he entrado en este apartado pero a partir de ahora tendré que entrar más veces ya que estoy estudiando una carrera que la gran mayoria de las cosas es programar.

  • Vale, vale no me cuentes tu vida y vamos al grano...

Para que sirve este post?

Este post sirve para poner cualquier problema que tengas con un programa. Ya sea trabajos de clase, programas por amor al arte. Cualquier cosas de dificultad aleatoria.

Normas

Normas u.u.. Normas, siempre normas!
Bueno, estas son unas cantas normas que creo que tendrían que ser obligatorias.

1ª: Este post es para pedir ayuda, que te vean errores o que te guíen durante tu aventura al programar. NO VENGAS A PEDIR QUE TE HAGAN TAL COSA Y TAL PASCUAL.
- Aventura... Frikazo...

2ª: Todos los post tendrán que estar organizados por 2 partes.


1ª: Introducción/Presentación del programa que estas haciendo y que crees que falla.
2ª: Codigo. 

3ª: Todo comentario tiene que ser constructivo. La opinión de el porque de los programas nos importa 0. Si uno quiere hacer una cosa tan inútil que ni sirve para lavarse el culo es cosa suya.

Idontknow

Primer de todo tengo que decir que estos problemas no los tengo que entregar y estoy practicando.

Aquí tenéis el problema que es en C:

Escribid un programa que, dada una matriz de enteros de 2 filas y 3 columnas (con los
valores introducidos a mano en el código), escriba las posiciones en las que se
encuentran los valores mínimo y máximo de la matriz.

El código que he echo hasta ahora, me lo he estado mirando mucho tiempo y no veo el error... No será hoy mi día o algo.
Un compañero me ha dicho que tengo demasiadas variables... yo veo las necesarias.. :S

#include <stdio.h>
#define files 2
#define columnes 3

int main()
{
int v[2][3]={0,1,2,3,4,5};
int i=0;
int j=0;
int max=v[0];
int min=v[0];
int maxi;
int mini;
int maxj;
int minj;

for (i=0;i<files-1;i++)
	{
	for(j=0;j<columnes-1;j++)
	{
		if(v[j]>max)
		{
			max=v[j];
			maxj=j;
			maxi=i;
		}
		if(v[j]<min)
		{
			min=v[j];
			minj=j;
			mini=i;
		}
	}
	}
printf("La posicio del valor maxim es:[%d,%d].\n",maxi,maxj);
printf("La posicio del valor minim es:`[%d,%d].\n",mini,minj);
}

Gracias de antemano.

#3

Son warning pero el resultado es ese y eso no me tendría que dar...

1 respuesta
corono

Que error te da?
Yo lo primero que he visto es que machacas el valor almacenado en "max" en la línea 23, por otro distinto en la linea 25, que supongo que tiene que ser en la variable maxi...

3 respuestas
Idontknow

#3 Joder... es verdad...

El maximo me da 0,1 i el minimo me va loco..

corono

#2 Solucionado entonces?

Edit: Veo que no:

Prueba a poner cuando haces las comparaciones en los if, y las asignaciones esto:

v(corchete)

A ver que tal.
Edit2: cago en todo, no se ve

pon la fila en la que estás a la hora de hacer las asignaciones v (corchete) i (corchete) (corchete) j (corchete)

Idontknow
for (i=0;i<files-1;i++)
	{
	for(j=0;j<columnes-1;j++)
	{
		if(v[i][j]>max)
		{
			max=v[j][i];
					}
		if(v[i][j]<min)
		{
			min=v[j][i];
					}
	}

#3 Asi?
#3 Retocado, he bajado de 6 warning a 4 ahora me da el minimo bien el maximo mal.

Retocado.

1 respuesta
corono

#6 sí, pero en el if (v[(i)][j]>max)
max = v[(i)][j];
sin los parentesis de [(i)], lo pongo así porque lo reconoce la cursiva, y te sobra un corchete en max y en min.

#6 la imagen está actualizada? has puesto en la linea 7 y 13 la i y la j al revés.
Utilizas linux?
Si tuviese una conexión decente te lo hago y subo en una foto pero es lo que tiene pillar el wifi de la uni en el piso XD.

1 respuesta
Idontknow

#7 Si ya lo he tocado ahora tengo esto y el minimo me da perfecto. El maximo mal.

for (i=0;i<files-1;i++)
	{
	for(j=0;j<columnes-1;j++)
	{
		if(v[i][j]>max)
		{
			max=v[i][j];
					}
		if(v[i][j]<min)
		{
			min=v[i][j];
					}
	}
1 respuesta
corono

#8 Prueba a inicializar las variables, pero no entiendo por qué al declarar max y min lo haces de esa forma.

int max=0, min=0;

for (i=0;i<files-1; i++)
{
   for (j=0; j<columnes-1; j++)
   {
      if (v[i][j]>=max) 
           max=v[i][j];
      if(v[i][j]<=min)
            min=v[i][j];
   }
}

#10 tienes que almacenar el valor máximo y mínimo en un vector? eso lo puedes hacer con vector de 2 posiciones (soluciones[2]).
Te sigue dando fallo con el codigo que he puesto?

2 respuestas
Idontknow

#9 El otro día me explicaron las arrays y hoy es el primer dia que me he puesto ha hacer ejercicios... sinceramente no se como declarar max i min para que sea un vector.
Y ya las tengo inicializadas.

1 respuesta
Idontknow

#9 Problema arreglado.

#include <stdio.h>
#define files 2
#define columnes 3

int main()
{
int v[2][3]={4,1,2,0,4,5};
int i=0;
int j=0;
int max=v[0][0];
int min=v[0][0];

for (i=0;i<files-1;i++)
	{
	for(j=0;j<columnes-1;j++)
	{
		if(v[i][j]>max)
		{
			max=v[i][j];
			
	}
	if(v[i][j]<min)
	{
		min=v[i][j];
		
	}
}
}
printf("La posicio del valor maxim es:[%d,%d].\n",max);
printf("La posicio del valor minim es:[%d,%d].\n",min);
}

Tenia que definir max i min como un vector que no lo hacia...

2 respuestas
corono

#11 me alegro que lo hayas solucionado, pero yo le cambiara el título por algo más acorde al contenido tipo "Problemas progrmando en c" o algo por el estilo, aunque por interné hay 100000 foros del estilo.

Idontknow

Te apoyo xD

Que algún mod lo cambie.

Gracias por la ayuda, por cierto.

CricK

#11 Has probado ese código de verdad?

Por un lado files-1 y columnes-1, serían ambas sin el -1

Con max=v[j]; guardas el valor, no la posición

printf(&quot;La posicio del valor maxim es:[%d,%d].n&quot;,max);
printf(&quot;La posicio del valor minim es:[%d,%d].n&quot;,min);

Con los printfs estás imprimiendo el valor no la posición del valor.
Además en el printf pones %d,%d que es para imprimir por pantalla dos valores, y tú sólo pones uno.

1 respuesta
Idontknow

#14 Lo de las file y columnes creo que esta bien ya que empiezas en 0 i tienes que hacer

1ra fila = 0
2da fila = 1

Y si filas es igual a 2 por lo tanto me contaría como una 3ra fila y se saldría de la array. Igual que en la columnas.

Y sí, respeto a lo del valor tienes razon xD. Eso me pasa por ir con prisas y tener la cabeza en otro lugares.

CricK

A ver, si es i<files-1

1ra
for (i=0;i<2-1;i++)
{
resto del código
}

2da
for (i=1;i<2-1;i++)
{
Ya no se ejecuta el resto del código porque i < 2-1 es igual a i < 1 que a su vez es 1 < 1, es falso, y no se ejecuta la segunda vez
}

Serviría i<=files-1

1 respuesta
Idontknow

#16 Estoy a topeh!

Ale, arreglado.

#include <stdio.h>
#define files 2
#define columnes 3

int main()
{
int v[2][3]={4,1,2,0,4,5};
int i=0;
int j=0;
int max=v[0][0];
int min=v[0][0];
int maxi=0;
int maxj=0;
int mini=0;
int minj=0;
for (i=0;i<=files-1;i++)
	{
	for(j=0;j<=columnes-1;j++)
	{
		if(v[i][j]>max)
		{
			max=v[i][j];
			maxi=i;
			maxj=j;
		}
		if(v[i][j]<min)
		{
			min=v[i][j];
			mini=i;
			minj=j;
			
	}
}
}
printf("La posicio del valor minim es:[%d,%d].\n",mini,minj);
printf("La posicio del valor maxim es:[%d,%d].\n",maxi,maxj);
}
Lecherito

Chacho, te me complicas la vida de unas maneras brutales xDDDD

int max=v[0][0];
int min=v[0][0];

Esas dos variables creo que no hacen falta para nada, ya que si haces un if (v[ i ][j] > v[maxi][maxj])... es código que te ahorras.

int v[2][3]={4,1,2,0,4,5};

Tio, si tienes un par de defines para las filas y las columnas, úsalo ahí también, eso luego podría dar lugar a equivocaciones ^^

Y lo de la condición del for, yo pondría como han dicho por ahí (i<filas) no (i<=filas-1)

Ya sé que son tonterías etc, pero siempre es bueno acostumbrarse jeje

PD: Ninjaedit, malditas cursivas xD

1 respuesta
Idontknow

#18 Gracias. Tendré que acostumbrarme a hacer las cosas mas senzillas

freskito24

Estoy con esta problema: (el resto del código es irrelevante) parto de una cadena de texto palabra y cuando tengo que usar la función palíndromo


#include <string.h>
#include <iostream>
using namespace std;

...etc... hasta que tengo que usar la función

bool palindromo(char palabra[40])
{
     int nletras = strlen(palabra) +1;
     cout << nletras << endl;
     char inversa[nletras];
     
for (int i = 0; i<nletras; i++){ inversa[i] = palabra[nletras -1]; } cout << inversa; return true; }

Se supone que pones una frase y te dice si es un palíndromo (se lee igual en los dos sentidos). El objetivo del programa no es un problema, pero el problema lo tengo en el bucle:

     for (int i = 0; i<nletras; i++){
         inversa[i] = palabra[nletras -1];
         }
     

No funciona como yo esperaba, invirtiendo la cadena, y da valores extraños como [[&€ y demás cosas.
¿Cuál es la sintaxis correcta para hacer eso?

1 respuesta
Lecherito

#20 lo que te pasa es que no estás comprobando si la primera letra es igual que la última, si la segunda es igual que la penúltima...

A lo bruto, (obvio no te voy a hacer el código) sería algo así

for (i=0;i<letras/2;i++) si palabra[ i] es igual que palabra[long-i] todo bien, si no que salga pa'fuera

Y de forma recursiva, si quieres te lo puedo decir, pero no sé si lo has dado aún o qué xD

PD: Espero no haberme equivocado, hace mil que no hago este tipo de cosas xDD

dagavi

Vaya líos que os metéis (aunque viendo algún código de mi primera asignatura de programación también veo que le daba 1000 vueltas a las cosas más simples).

Primero de todo, si tienes una variable que se llama "numero de letras" y el objetivo es que guarde cuantas letras tiene el string, ¿porque le sumas un 1 artificial?

"Pan" tiene 3 letras (útiles) no 4 (el '\0' ahora no te hace falta).

Así que puedes crear el vector con nletras + 1 (en vez de modificar la variable nletras), lo veo más correcto.

Por otro lado:

for (int i = 0; i<nletras; i++){
    inversa[i] = palabra[nletras -1];
}

No se si te has dado cuenta (supongo que no), pero estás copiando todo el rato "palabra[nletras - 1]", es decir, todo el rato la misma posición, te faltaría meterle "palabra[nletras - 1 - i]" para que en cada iteración cambie de letra. Igualmente tampoco funciona por haber puesto que "nletras" es strlen + 1, por lo que la primera letra que copias es ' \0' y al escribir el string acaba en el primer carácter.

Si mantuvieras nLetras = strlen(palabra);

Puedes declarar invertido como [nletras + 1] //quiero nLetras y alado 1 para el '\0'

hacer la copia

 for (inti = 0; i < nLetras; ++i) inversa[i] = palabra[nLetras - 1 - i];
inversa[nLetras] = '\0'; // Fuera del bucle;

Aun así para saber si una palabra es palíndroma no tienes que crear un vector copiarlo y después ver si la posición palabra[ i] = inversa[ i] para toda i, solo tienes que mirar si palabra[ i] == palabra[nLetras - 1 - i];

No pienses en programar, piensa en que harías, si te dicen: ¿Es palíndroma esta palabra? ¿Tu que harías? ¿copiarías la palabra a la inversa en una libreta y después compararías las dos palabras? ¿o simplemente miraría si la primera letra es igual a la última, si la segunda es igual a la penúltima, y así hasta llegar a la mitad? (porque a partir de la mitad es repetir lo que ya ha comprobado)

1 respuesta
freskito24

#22 Gracias por la respuesta, es mi segundo día en C++ y aun estoy muy verde, además de que los tutoriales por los que estoy aprendiendo no me parecen muy buenos.

No tenía ni idea de lo de las letras útiles, creía si tenía que introducir una cadena de 4 caracteres tenía que poner cadena[5]="1234"; por eso puse el +1, porque devolvía 4, y necesitaba 5. Lo he vuelto a leer y ahora veo que empieza a contar desde 0. Gracias por la corrección

Bueno, ahora tengo el siguiente problema

     int nletras = strlen(palabra);
     cout << nletras << endl;
     char inversa[nletras];
     cout << strlen(inversa);

strlen(inversa) devuelve 0 y nletras vale 4 de la cadena palabra[4]="1234";
No entiendo nada :wtf:

Respecto a tu último apunte: Claro que se me había ocurrido, pero el objetivo era probar cosas con las cadenas (las cuales odio ahora mismo), no ver si la palabra era palíndroma xD

dagavi

A ver, vamos por partes xD

En "1234" hay 4 letras pero 5 bytes/chars, si quieres hacer otro vector que contenga lo mismo tiene que ser de tamaño 5.

strlen cuenta el numero de letras en un string. Un string siempre acaba con el carácter '\0', si haces:

char inversa[nletras];
cout << strlen(inversa);

Es normal que no te de 4, le estás metiendo basura a la función, no está inicializado el contenido.

Aun así para no extenderme hago el código comentado y listo, a ver si como ejemplo te vale y lo entiendes.

bool palindromo(char palabra[40]) {
    int nletras = strlen(palabra);
    cout << palabra << " tiene " << nletras << " letras" << endl;
     
// Queremos guardar nletras letras + el finalizador '\0' char inversa[nletras + 1]; // Recorremos todas las letras del string original. ¿Cuantas hay? nletras for (int i = 0; i < nletras; ++i) { inversa[i] = palabra[nletras - 1 - i]; // Hay N letras, pero como empieza en 0 la última posición es // nletras - 1, a partir de ahí restamos el índice 0..nletras } // Hemos copiado las letras, falta añadir el finalizador al string inverso: inversa[nletras] = '\0'; cout << "Palabra inversa: " << inversa << endl; return true; }
1 1 respuesta
freskito24

#24 vale, ahora veo mi error. Hay tantas cosas que no sé sobre este lenguaje que si tengo un error que no sea de sintaxsis me vuelvo loco. Gracias por el código comentado.

dagavi

Una duda que me ha surgido.

En Java, ¿como veríais la mejor forma de realizar un callback?

Supongamos que tenemos una clase Interfaz y otra Controlador.
Pongamos que cuando se pica un botón la interfaz lanza un thread con controlador (pongamos que el propio controlador implementa run o runnable) y pone algún mensajito en pantalla de "Ocupado" y continúa con el bucle estándar de la interfaz gráfica.

El controlador, en su thread, ejecuta cierto código y genera algún resultado, y debe avisar a la interfaz (en este ejemplo) de que ya ha acabado.

A primera vista lo que podemos pensar hacer es lo típico: le paso mi instancia de "Interfaz" y que cuando acabe que llame a "interfaz.accionCompletada()", pero esto es muy warro, se acopla completamente con la clase Interfaz, si lo queremos reusar en otra cosa no nos vale / es una mierda.

Para esto podemos crear entonces una interface "interface ControladorCallback", y que Interfaz (y cualquier otra cosa que quiera obtener un callback) la implemente, vamos, un patrón observador, pero no me termina de convencer lo de tener que hacer que la clase implemente interfazs solo para poder recibir un simple callback.

He probado un posible ejemplo que pongo a continuación por si a alguien también le interesara, pero es muy simple:

spoiler

Sin embargo veo bastante más útil un sistema como el que utilizan algunas librerías de interfaces gráficas, en el que se instancian "Listeners" y se le van añadiendo al elemento a observar. Eso sin contar con una sola clase se pueden implementar todas las callbacks. Además de ser muy simple pasar del modelo anterior a este, solo hay que cambiar la forma de usar las interfazs.

De nuevo, dejo un pequeño código por si a alguien le interesa.

spoiler

Pues eso, para los que tienen más experiencia. ¿Cual es la mejor forma veis de implementar un callback? ¿Alguna otra forma? ¿Usando alguna función de la API de Java que desconozco y que da solución a este problema?

2 respuestas
BLZKZ

#26 "Interficie"

Por dios di o interfaz (en español) o interface (en inglés). Lo digo porque me ha llamado mucho la atención. A lo del callback ni idea, a tanto no llego en java xD

1 respuesta
dagavi

#27 Pues serán por profesores que dicen "Interficie", "Interficies" xD Aunque bueno, te lo cambio xD

1 respuesta
BLZKZ

#28 si hay mucha gente que lo dice, pero es que me chirría xD amén de que no es una expresión admitida xD

Siento que sea esto lo unico que pueda decirte al respecto :(

MTX_Anubis

#26 En la propia API de java tienes las interfaces Observer y la clase Observable para extender de ella aunque yo no recomiento utilizarlas.

Imagino que estás utilizando el patrón MVC. Lo suyo es que la vista sea listener del modelo y cuando el modelo cambia, envíe eventos que son recogidos por la vista.

Sí, es copiar el diseño de los listeners de swing o todas las apis gráficas xD

El patrón callback es algo diferente a esto de todas formas :P

1 respuesta

Usuarios habituales

  • Amazon
  • Idontknow
  • freskito24
  • dagavi
  • BLZKZ
  • CricK
  • corono