validacion de puntos geograficos, grados, minutos, segundos y comparacion

Iniciado por Beginner Web, 13 Diciembre 2018, 04:43 AM

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

Beginner Web

Necesito algo de ayuda con los modulos de validacion de puntos geograficos, latitud, longitud y comparacion de dos puntos geograficos , me parece que algo estoy haciendo mal en el segundo y no quiero colocar todo en un solo if  :(
Código (cpp) [Seleccionar]
#include <iostream>
#include <stdlib.h>
#include <string.h>

using namespace std;

typedef struct coordenadas{
int grados;
int minutos;
int segundos;
char direccion;
};
typedef struct punto_geografico{
coordenadas latitud;
coordenadas longitud;
};

void crear(coordenadas &c, bool latitud);
bool validar(coordenadas p, bool latitud);
bool iguales(punto_geografico p, punto_geografico q);
void determinar_ubicacion(punto_geografico p);

int main()
{
punto_geografico p, q;
cout<<"Crear primer punto geografico"<<endl;
cout<<"Latitud"<<endl;
crear(p.latitud,1);
cout<<"Longitud"<<endl;
crear(p.longitud,0);
cout<<"Crear segundo punto geografico"<<endl;
cout<<"Latitud"<<endl;
crear(q.latitud,1);
cout<<"Longitud"<<endl;
crear(q.longitud,0);
if(iguales(p,q)==true)
cout<<"Son iguales"<<endl;
else
cout<<"Son diferentes"<<endl;
determinar_ubicacion(p);
system("pause");
}

void crear(coordenadas &c, bool latitud)
{
do{
cout<<"Ingrese grados   : ";
cin>>c.grados;
cout<<"Ingrese minutos  : ";
cin>>c.minutos;
cout<<"Ingrese segundos : ";
cin>>c.segundos;
cout<<"Ingrese direccion: ";
cin>>c.direccion;
}while(validar(c,latitud)==false);
}
//Aqui
bool validar(coordenadas c, bool latitud)
{
if(latitud==true){
if(c.direccion=='N' || c.direccion=='S'){
if(c.grados==90 && c.minutos==0 && c.segundos==0)
return true;
else{
if(c.grados<0 || c.grados>89 || c.minutos<0 || c.minutos>59 || c.segundos<0 || c.segundos>59)
return false;
else
return true;
}
}
else
return false;
}
else{
if(c.direccion=='E' || c.direccion=='O'){
if(c.grados==180 && c.minutos==0 && c.segundos==0)
return true;
else{
if(c.grados<0 || c.grados>179 || c.minutos<0 || c.minutos>59 || c.segundos<0 || c.segundos>59)
return false;
else
return true;
}
}
else
return false;
}
}
//Y aqui
bool iguales(punto_geografico p, punto_geografico q)
{
if(p.latitud.direccion==q.latitud.direccion && p.longitud.direccion==q.longitud.direccion){
if(p.latitud.grados==q.latitud.grados && p.longitud.grados==q.longitud.grados)
if(p.latitud.minutos==q.latitud.minutos && p.longitud.minutos==q.longitud.minutos)
if(p.latitud.segundos==q.latitud.segundos && p.longitud.segundos==q.longitud.segundos)
return true;
}
else
return false;
}

void determinar_ubicacion(punto_geografico p)
{
cout<<"El punto geografico se ubica en";
if(p.latitud.direccion=='N')
cout<<" el hemisferio Norte ";
else
cout<<" el hemisferio Sur ";
if(p.longitud.direccion=='E')
cout<<"Oriental"<<endl;
else
cout<<"Occidentel"<<endl;
}
7w7

MAFUS

Dentro de iguales: Quita las llaves del primer if y la palabra else.

Beginner Web

Asi?
Código (cpp) [Seleccionar]
bool iguales(punto_geografico p, punto_geografico q)
{
if(p.latitud.direccion==q.latitud.direccion && p.longitud.direccion==q.longitud.direccion)
if(p.latitud.grados==q.latitud.grados && p.longitud.grados==q.longitud.grados)
if(p.latitud.minutos==q.latitud.minutos && p.longitud.minutos==q.longitud.minutos)
if(p.latitud.segundos==q.latitud.segundos && p.longitud.segundos==q.longitud.segundos)
return true;

return false;
}
7w7

MAFUS

Sí, sólo si se cumple la cadena de ifs llegas a return true, en caso contrario acabarás en return false.

CalgaryCorpus

Hay mucha redundancia posible de eliminar.
Sugiero hacer una funcion que compare 2 coordenadas

Código (cpp) [Seleccionar]
bool iguales(coordenadas c1, coordenadas c2);

y este se use en la comparacion de punto_geografico

Código (cpp) [Seleccionar]
bool iguales(punto_geografico p1, punto_geografico p2) {
   return iguales(p1.longitud, p2.longitud) &&
          iguales(p1.latitud, p2.latitud);
}


y dado que los valores de los elementos de una coordenada estan limitados, sugiero hacer una conversion de los numeros antes de compararlos.

Por ejemplo:

Código (cpp) [Seleccionar]
long convertir(coordenadas c) {
   return c.grados* 10000 + c.minutos*100 + c.segundos;
}


En el fondo lo que se quiere hacer, si es que la aritmetica no me falla, es convertir 3 numeros sueltos en un solo numero: por ejemplo:  grados 165, minutos 32, segundos 87 se convierte en 1653287.

Con ello se hace 1 sola comparacion numerica y 1 del caracter.
iguales (la version que compara de coordenadas) se transforma en:

Código (cpp) [Seleccionar]
bool iguales(coordenadas c1, coordenadas c2) {
    return c1.direccion == c2.direccion &&
           convertir(c1) == convertir(c2);
}


Aqui mi perfil en LinkedIn, invitame un cafe aqui

Beginner Web

#5
Primero que nada perdon por el spam y... bueno lo he dejado asi porque es mas estetico para mi no se, de que funciona funciona pero seguro muchos diran que no es buena practica lo se perdon  :-(
Código (cpp) [Seleccionar]
bool iguales(punto_geografico p, punto_geografico q)
{
bool igual=true;
if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
if(p.latitud.grados!=q.latitud.grados || p.longitud.grados!=q.longitud.grados)
igual=false;
if(p.latitud.minutos!=q.latitud.minutos || p.longitud.minutos!=q.longitud.minutos)
igual=false;
if(p.latitud.segundos!=q.latitud.segundos || p.longitud.segundos!=q.longitud.segundos)
igual=false;
return igual;
}

Si alguien me sugiere algo mas de buenas tecnicas de programacion o estetica me lo hace saber, mi compañero puso todo en un solo if pero vaya que quedo un chorizo de codigo y a mi no me gusto pero era eficiente igual, se que esto esta mal porque al encontrar la primer condicion que no se cumple ya deberia retornar un false y dejar de verificar las siguientes condiciones :(  :laugh:
7w7

K-YreX

Cita de: Beginner Web en 14 Diciembre 2018, 02:12 AM
se que esto esta mal porque al encontrar la primer condicion que no se cumple ya deberia retornar un false y dejar de verificar las siguientes condiciones

Para dejar de verificar condiciones lo que se suele hacer es incluir que <igual> sea <true> en cada <if>.
Código (cpp) [Seleccionar]

bool iguales(punto_geografico p, punto_geografico q){
bool igual=true;
if(igual && (p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion))
igual=false;
if(igual && (p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion))
igual=false;
// asi con todos
return igual;
}


Sin embargo esto se hace más cuando en vez de <if> tienes un <while> o un <for>. Para un <if> es mejor usando <else>. Así en cuanto se cumpla un <if> el resto se los va a saltar.
Código (cpp) [Seleccionar]

bool iguales(punto_geografico p, punto_geografico q){
bool igual=true;
if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
else if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
       else if(p.latitud.grados!=q.latitud.grados || p.longitud.grados!=q.longitud.grados)
               igual=false;
// asi con todos
return igual;
}


Y otra opcion es asignar cada condición dentro de cada <if> a la propia variable <igual> ya que es booleana. En este caso tendrías que hacerlo negándolas, algo así:
Código (cpp) [Seleccionar]

bool iguales(punto_geografico p, punto_geografico q){
bool igual=true;
if(igual)
igual= !(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
       if(igual)
igual= !(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
       if(igual)
               igual= !(p.latitud.grados!=q.latitud.grados || p.longitud.grados!=q.longitud.grados)
// asi con todos
return igual;
}

Un poco raro pero se puede hacer. Puedes elegir la que mejor veas. :-X
PD: Me acabo de dar cuenta de que los dos primeros condicionales son el mismo. :rolleyes:
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

Beginner Web

Cita de: YreX-DwX en 14 Diciembre 2018, 03:11 AM
Para dejar de verificar condiciones lo que se suele hacer es incluir que <igual> sea <true> en cada <if>.
Código (cpp) [Seleccionar]

bool iguales(punto_geografico p, punto_geografico q){
bool igual=true;
if(igual && (p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion))
igual=false;
if(igual && (p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion))
igual=false;
// asi con todos
return igual;
}


Sin embargo esto se hace más cuando en vez de <if> tienes un <while> o un <for>. Para un <if> es mejor usando <else>. Así en cuanto se cumpla un <if> el resto se los va a saltar.
Código (cpp) [Seleccionar]

bool iguales(punto_geografico p, punto_geografico q){
bool igual=true;
if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
else if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
       else if(p.latitud.grados!=q.latitud.grados || p.longitud.grados!=q.longitud.grados)
               igual=false;
// asi con todos
return igual;
}


Y otra opcion es asignar cada condición dentro de cada <if> a la propia variable <igual> ya que es booleana. En este caso tendrías que hacerlo negándolas, algo así:
Código (cpp) [Seleccionar]

bool iguales(punto_geografico p, punto_geografico q){
bool igual=true;
if(igual)
igual= !(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
       if(igual)
igual= !(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
       if(igual)
               igual= !(p.latitud.grados!=q.latitud.grados || p.longitud.grados!=q.longitud.grados)
// asi con todos
return igual;
}

Un poco raro pero se puede hacer. Puedes elegir la que mejor veas. :-X
PD: Me acabo de dar cuenta de que los dos primeros condicionales son el mismo. :rolleyes:
Me quede con la segunda opcion, la tercera me gusta pero es algo rara ero si la entiendo
Código (cpp) [Seleccionar]
bool iguales(punto_geografico p, punto_geografico q)
{
bool igual=true;
if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
else if(p.latitud.direccion!=q.latitud.direccion || p.longitud.direccion!=q.longitud.direccion)
igual=false;
else if(p.latitud.grados!=q.latitud.grados || p.longitud.grados!=q.longitud.grados)
igual=false;
else if(p.latitud.minutos!=q.latitud.minutos || p.longitud.minutos!=q.longitud.minutos)
igual=false;
else if(p.latitud.segundos!=q.latitud.segundos || p.longitud.segundos!=q.longitud.segundos)
igual=false;
return igual;
}
7w7

K-YreX

Lo único que los dos primeros condicionales son el mismo...   :rolleyes:
Me he dado cuenta después y aunque lo he añadido al mensaje anterior igual lo he puesto demasiado tarde
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;