Matriz con puntos de silla (lenguaje C)

Iniciado por NOB2014, 12 Agosto 2014, 19:54 PM

0 Miembros y 1 Visitante están viendo este tema.

NOB2014

Hola gente.
Tengo un error con la validación de datos en este programa y por más que práctico no logro dar con la tecla.-
Debo reconocer que puedo estar cometiendo un error que ya debería resolver por mi mismo pero me pase 2 días de 8 horas cada uno para hacer que funcionara la matriz de punto de silla y cuando lo logré (bueno creo que lo logré porque lo corrí más de 50 veces y nunca me sale la tabla con la coincidencia) me aparece este error que deseo que me ayuden a resolver porque quiero dejar perfectamente establecida la forma correcta de utilizar fgets.-

/*
Se dice que una matriz tiene un punto de silla si alguna posición de la matriz
es el menor valor de su fila, y a la vez el mayor de su columna.-
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h> 
#include <ctype.h>

#define MAX_VECTOR 2
#define MAX_F_C 10


void verificaFil(int *intFil);
void verificaCol(int *intFil);
void ingreso(int matriz[], int intFil, int intCol);
void puntoDeSilla(int matriz[], int intFil, int intCol);


int main(void){
int intFil=0, intCol=0, *matriz=NULL;

printf("\n\n ===== El programa le mostrara los puntos de silla (si los hay) =====\n\n");
verificaFil(&intFil);
verificaCol(&intCol);
matriz = malloc(intFil * intCol * sizeof(int));

ingreso(matriz, intFil, intCol);

puntoDeSilla(matriz, intFil, intCol);

free(matriz);
printf("\n\n");
return 0;
}

void verificaFil(int *intFil){
char charFil[MAX_F_C+1]={'\0'}, *p=NULL;
unsigned int ch=0, i=0, ok=0;

do{
printf(" Ingrese un entero para establecer la cantidad de filas (m%cximo %d)......:", 160,MAX_F_C);
fgets(charFil,  MAX_F_C, stdin);

if((p=strchr(charFil, '\n'))!=0){
*p='\0';
}
else{
while((ch = getchar()) !='\n' && ch!=EOF);
}

ok=0;
for(; charFil[i]; i++){
if(!isdigit(charFil[i])){
ok++;
}
}
if(ok==0){
*intFil = atoi(charFil);
(*intFil == 0 || *intFil > MAX_F_C) ? ok=1 : ok;
}
}while(ok !=0);
}

void verificaCol(int *intCol){
char charCol[MAX_F_C+1]={'\0'}, *p=NULL;
unsigned int ch=0, i=0, ok=0;

printf("\n");
do{
printf(" Ingrese un entero para establecer la cantidad de columnas (m%cximo %d)...:", 160,MAX_F_C);
fgets(charCol,  MAX_F_C, stdin);

if((p=strchr(charCol, '\n'))!=0){
*p='\0';
}
else{
while((ch = getchar()) !='\n' && ch!=EOF);
}

ok=0;
for(; charCol[i]; i++){
if(!isdigit(charCol[i])){
ok++;
}
}

if(ok==0){
*intCol = atoi(charCol);
(*intCol == 0 || *intCol > MAX_F_C) ? ok=1 : ok;
}
}while(ok !=0);
}

void ingreso(int matriz[], int intFil, int intCol){
unsigned int hora = time(NULL), i=0, j=0, indice=0;
srand(hora); 

for(; i < intFil; i++){
for(j=0; j < intCol; j++){
indice = i * intCol + j;
matriz[indice] = rand ()% 100;
}
}

printf("\n");
for(i=0; i<intFil; i++){
for(j=0; j<intCol; j++){
indice = i * intCol + j;
printf(" %3d", matriz[indice]);
}
if(j%intCol==0) printf("\n");
}

}

void puntoDeSilla(int matriz[], int intFil, int intCol){
int i, j, elMenor=0, colMen=0, indice=0, noPds;

for(i = 0; i < intFil; i++){
noPds = 0;
indice = intCol * i;
elMenor=matriz[indice];
colMen =  indice-(intCol*i);

for(j=0; j < intCol; j++){
if(matriz[indice] < elMenor){
elMenor = matriz[indice];
colMen =  indice-(intCol*i);
}
indice++;
}

for(j=0; j < intFil; j++){
indice = j * intCol + colMen;
if(matriz[indice] > elMenor){
noPds++;
}
}
if(noPds == 0)
printf("\n en la fila %d columna %d hay punto de silla", i, colMen);
}
}


  Uno de los ingresos incorrectos:
  Ingreso...: -4 (incorrecto)
  Ingreso...: aa (incorrecto)
  Ingreso...: 11 (incorrecto)
  Ingreso...: -4 (correcto)

Bueno espero que me puedan ayudar y no vacilen en cambiar todo lo que deseen cambiar de mi código, es así como puedo aprender cosas que no están en los manuales.- 
   
Saludos y un gran abrazo
Daniel.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

Blaster

Cita de: NOB2014 en 12 Agosto 2014, 19:54 PM
  Uno de los ingresos incorrectos:
  Ingreso...: -4 (incorrecto)
  Ingreso...: aa (incorrecto)
  Ingreso...: 11 (incorrecto)
  Ingreso...: -4 (correcto)

En las funciones tanto VerificaCol() y VerificaFil() la variable i la debes inicializar a cero dentro del for:

Código (cpp) [Seleccionar]
for(i = 0; charCol[i]; i++)
  if (!isdigit(charCol[i]))
    ok++;


Saludos


NOB2014

Hola Blaster.
Muchas gracias ahora funciona correctamente, yo inicializaba la variable i en 0 fuera del bucle sólo que funcionaba si el primer ingreso era correcto pero de no ser así valía cada vez más.-
Una cosa que descubrí es que haciendo una tabla de 1 fila y x columnas el programa funciona correctamente.-
Sólo me resta que alguien me diga que parte del código haría de otra manera, por lo menos para aprender algo más de los expertos.-       

Saludos.
Daniel
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

leosansan

#4
Cita de: NOB2014 en 12 Agosto 2014, 19:54 PM
Hola gente.
Tengo un error con la validación de datos en este programa y por más que práctico no logro dar con la tecla.-
Debo reconocer que puedo estar cometiendo un error que ya debería resolver por mi mismo pero me pase 2 días de 8 horas cada uno para hacer que funcionara la matriz de punto de silla y cuando lo logré (bueno creo que lo logré porque lo corrí más de 50 veces y nunca me sale la tabla con la coincidencia) me aparece este error que deseo que me ayuden a resolver porque quiero dejar perfectamente establecida la forma correcta de utilizar fgets.-
..........................................

Bienvenido otra vez amigo Daniel.

El código funciona perfecto pero pretender que de forma aleatoria te salga un punto de silla es mucho pedir.  :o

Te aconsejo introducir a mano una matriz que sepas que tiene punto de silla y así compruebas que el código funciona O.K.

Cambia a:

Código (cpp) [Seleccionar]
void ingreso(int matriz[], int intFil, int intCol){
unsigned int hora = time(NULL), i=0, j=0, indice=0;
srand(hora);

for(; i < intFil; i++){
for(j=0; j < intCol; j++){
indice = i * intCol + j;
printf("Introduzca la posicion %d, %d: ", i+1, j+1);
scanf ("%d",&matriz[indice]);
//matriz[indice] = rand ()% 100;
}
}
printf("\n");
for(i=0; i<intFil; i++){
for(j=0; j<intCol; j++){
indice = i * intCol + j;
printf(" %3d", matriz[indice]);
}
if(j%intCol==0) printf("\n");
}
}


e introduce como ejemplo de matriz con punto de silla:

Código (cpp) [Seleccionar]

   1       2       3
   2       3       4
   1       5       2


Y de paso cambia, para que el resultado sea más chachi en la función puntoDeSilla:

Código (cpp) [Seleccionar]
printf("\n en la fila %d columna %d hay punto de silla", i+1, colMen+1);

Veras como sí que detecta el punto de silla en la fila 2 y columna 1, con los cambios que te he mencionado, claro.  ;)

Lo dicho, un fuerte saludo Daniel de tu amigo León.

¡¡¡¡ Saluditos! ..... !!!!




Sorry!, ya han contestado mientras escribía esto.

kutcher

#5
Para ser un punto de silla debe cumplir una de estas dos condiciones:

1) Dentro de la fila son mínimos y dentro de la columna son máximos
2) Dentro de la fila son máximos y dentro de la columna son mínimos

En tu función solo verificas el primer punto si al generarse una matriz con estos elementos:

Código (cpp) [Seleccionar]
2, 5, 12,
3, 2, 25,
8, 1, 20


Donde en la fila 0 y columna 2 existe un punto de silla, el cual el programa no procesa


leosansan

#6
Cita de: kutcher en 12 Agosto 2014, 22:23 PM
Para ser un punto de silla debe cumplir una de estas dos condiciones:

1) Dentro de la fila son mínimos y dentro de la columna son máximos
2) Dentro de la fila son máximos y dentro de la columna son mínimos


Me debo estar quedando obsoleto, ¡los años no pasan en balde!.

Yo me quedé en la definición primera como punto de silla , para nada la segunda. Sniff!!!!!...¿o tal vez esté en lo cierto?.  :silbar:

¡¡¡¡ Saluditos! ..... !!!!



NOB2014

Hola Leo.
Amigo, muchas gracias por estar siempre allí con tus aportes, lo que propones de ingresar los datos a mano es lo correcto simplemente me resultaba tedioso luego de estar 2 días con lo mismo.-
Kutcher, gracias por responder, el siguiente es el enunciado del manual con el cual estoy estudiando, por eso lo hice de esa manera, pero me suena que mientras buscaba información en internet, en algunos sitios dice algo como eso, desconozco todavía si es válido de las dos maneras.-     



Saludos.
Daniel
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

ivancea96

Yo diría que la definición de Kutcher es la real. Pero si ese ejercicio te lo manda un profesor o algo así, pregúntale a él.

NOB2014

Hola Ivance96.
Gracias por tu aporte, no tengo a quien consultar, tengo 62 años y soy un autodidacta que aprende y mucho gracias a Uds.
Por lo que pude consultar hasta el momento adhiero a lo que decis.-

Saludos.
Daniel
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-