Dev - C++ - Ordenar y mostrar datos en columnas

   
Vista:

Ordenar y mostrar datos en columnas

Publicado por connectee (4 intervenciones) el 15/01/2016 12:35:57
¡Hola a todos!

Estoy haciendo una salida de datos en forma de tabla como la siguiente:

----------------------------------------------------------+
planeta posición hora horaInt minutoInt |
----------------------------------------------------------+
Mercurio horizonte-Este 0.65 12 8 |
Venus horizonte-Este 0.80 2 12 |
Marte horizonte-Este 1.50 4 18 |
Júpiter horizonte-Este 2.20 0 39 |
Saturno horizonte-Este 3.50 6 30 |
Urano horizonte-Este 3.50 3 52 |
Neptuno horizonte-Este 3.87 13 42 |
Mercurio horizonte-Este 4.30 14 25 |
Venus horizonte-Este 5.50 1 30 |
Marte horizonte-Este 5.60 5 36 |
Júpiter horizonte-Este 6.10 12 39 |
Saturno horizonte-Este 6.50 6 6 |
Urano horizonte-Este 6.90 3 30 |
Neptuno horizonte-Este 12.13 13 54 |
Mercurio horizonte-Este 12.65 15 42 |
Venus horizonte-Este 13.70 0 48 |
Marte horizonte-Este 13.90 6 54 |
Júpiter horizonte-Este 14.00 14 39 |
Saturno horizonte-Este 14.42 5 30 |
Urano horizonte-Este 14.65 3 30 |
Neptuno horizonte-Este 15.70 14 0 |
----------------------------------------------------------+

Se parte del arrayHoras que contiene datos ficticios de la hora en que pasa un planeta por el horizonte.
La tabla tiene las siguientes columnas: indent, planeta, posición, hora, horaInt, minutoInt.
Ellas corresponden a las variables del struct ListPosiciones.

Por primera vez hago algo parecido y no tengo ningún ejemplo de guiarme.
Al principio pensaba hacer cada columna con vectores, pero me parecía
muy difícil mantener el paralelismo entre ellos. Entonces decidí utilizar
estructuras (struct) para cada línea de la tabla. Pensaba hacerlo de esta
manera para ligar el conjunto de variables del struct. Y todo (me parecía
que) iba bien hasta que intenté ordenar las filas por ‘hora’. La sorpresa
para mí es que el resto de los elementos del struct no le siguen.

Comparan la salida con el algoritmo de ordenar y sin él!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
 
struct ListPosiciones{
    string  indent,
            nombrePlaneta,
            posición;
    float   hora;
    unsigned short  horaInt,
                    minutoInt;
};
 
void tablaLista(ListPosiciones arrayL[], float arrHoras[][7])
{
    string nombrePlaneta;
    unsigned short horaInt, minutoInt;
    float hora ;
    int el = 0;
    for(int fila = 0; fila < 3; ++fila){
        for(int col = 0; col < 7; ++col){
            switch(col){
                case 0: nombrePlaneta = "Mercurio";
                    break;
                case 1: nombrePlaneta = "Venus";
                    break;
                case 2: nombrePlaneta = "Marte";
                    break;
                case 3: nombrePlaneta = "Júpiter";
                    break;
                case 4: nombrePlaneta = "Saturno";
                    break;
                case 5: nombrePlaneta = "Urano";
                    break;
                case 6: nombrePlaneta = "Neptuno";
                    break;
            }
 
            hora        = arrHoras[fila][col];
            horaInt     = floor(hora);
            minutoInt   = round((hora - horaInt)*60);
 
            arrayL[el].indent        = "    ";
            arrayL[el].nombrePlaneta = nombrePlaneta;
            arrayL[el].posición      = "horizonte-Este";
            arrayL[el].hora          = hora;
            arrayL[el].horaInt       = horaInt;
            arrayL[el].minutoInt     = minutoInt;
 
            ++el;
        }
    }
}
 
void leerLista(ListPosiciones arrayL[])
{
    cout<<"----------------------------------------------------------+"<<endl;
    cout<<"    planeta"<<"\tposición "<<"\thora  "<<"\thoraInt"<<"\tminutoInt |"<<endl;
    cout<<"----------------------------------------------------------+"<<endl;
    for(int el = 0; el < 21; ++el){
        cout<<arrayL[el].indent<<' ';
        cout<<arrayL[el].nombrePlaneta<<' ';
        cout<<'\t';
        cout<<arrayL[el].posición<<' ';
        cout<<right<<setw(5)<<setprecision(2)<<fixed<<arrayL[el].hora<<'\t';
        cout<<right<<setw(2)<<fixed<<arrayL[el].horaInt<<' ';
        cout<<'\t'<<right<<setw(3)<<fixed<<arrayL[el].minutoInt<<"\t  |"<<endl;
    }
    cout<<"----------------------------------------------------------+"<<endl;
}
 
int main()
{   // el array de datos ficticios
    float arrayHoras[3][7] = // horas
    {   // Mercurio,   Venus,  Marte,  Júpiter,    Saturno,    Urano,  Neptuno
            {12.13,     2.2,    4.3,    0.65,       6.5,        3.87,   13.7},
            {14.42,     1.5,    5.6,    12.65,      6.1,        3.5,    13.9},
            {15.7,      0.8,    6.9,    14.65,      5.5,        3.5,    14  },
    };
 
    ListPosiciones arrayL[21];
 
    tablaLista(arrayL, arrayHoras);
//--- algoritmo de ordenar el array ----------------------
/*    int startScan, minÍndice;
    float minValor;
    for (startScan = 0; startScan < (21 - 1); startScan++){ // 21 es los elementos del array
        minÍndice = startScan;
        minValor = arrayL[startScan].hora;
            for(int cont = startScan + 1; cont < 21; cont++){
                if (arrayL[cont].hora < minValor){
                    minValor = arrayL[cont].hora;
                    minÍndice = cont;
                }
            }
        arrayL[minÍndice].hora = arrayL[startScan].hora;
        arrayL[startScan].hora = minValor;
    }*/
//--------------------------------------------------------
    leerLista(arrayL);
 
    return 0;
}


¿Cómo puedo “ligar” todos los datos al ordenar por algún dato (criterio)?
¿Existe algoritmo de la biblioteca estándar para resolver este ejemplo?

También tengo problema en escribir los prototipos de leerLista() y tablaLista().
Supongo que es por haber alguna dependencia de la declaración del struct ListPosiciones.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Ordenar y mostrar datos en columnas

Publicado por agustin (308 intervenciones) el 15/01/2016 16:31:59
O bien copias todos los elementos de la estructura uno por uno para que "le sigan", o usas memcpy y copias el bloque de memoria de la estructura completa indicando el tamaño de esta.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ordenar y mostrar datos en columnas

Publicado por connectee (4 intervenciones) el 19/01/2016 15:48:12
Gracias, agustin!

Soy principiante y tu comentario me puso pensativo…
Busqué información sobre los conceptos que mencionas,
pero no llegué a nada con ellos. Pese a eso, encontré un
ejemplo pertinente y lo acoplé a mi ejemplo. Una versión
simplificada (más que nada simplifiqué el struct) del mi
programa es la siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <list>
#include <iostream>
using namespace std;
 
struct Paquete_de_datos {
    string _planeta;
    float _hora;
};
 
bool mayorNúmeros(const Paquete_de_datos& a, const Paquete_de_datos& b){
    return a._hora < b._hora;
}
 
void tablaLista( list<Paquete_de_datos>& L, float arrHoras[][7])
{
    Paquete_de_datos línea;
    string planeta;
 
    for(int fila = 0; fila < 3; ++fila){
        for(int col = 0; col < 7; ++col){
            switch(col){
                case 0: planeta = "Mercurio";
                    break;
                case 1: planeta = "Venus";
                    break;
                case 2: planeta = "Marte";
                    break;
                case 3: planeta = "Júpiter";
                    break;
                case 4: planeta = "Saturno";
                    break;
                case 5: planeta = "Urano";
                    break;
                case 6: planeta = "Neptuno";
                    break;
            }
 
            float hora        = arrHoras[fila][col];
            línea._planeta  = planeta;
            línea._hora     = hora;     // variable de ordenar
 
            L.push_back(línea);
        }
    }
}
 
void mostrar(const list<Paquete_de_datos>& L) {
    list<Paquete_de_datos>::const_iterator it = L.begin();
    for (int k = 0; it != L.end(); ++it, ++k)
        if(k >0) cout << it->_planeta<<'\t'<<"| "<<it->_hora<<" |"<<endl;
}
 
int main()
{
    float arrayHoras[3][7] = // horas
    {   // Mercurio,   Venus,  Marte,  Júpiter,    Saturno,    Urano,  Neptuno
            {12.13,     2.2,    4.3,    0.65,       6.5,        3.87,   13.7},
            {14.42,     1.5,    5.6,    12.65,      6.1,        3.5,    13.9},
            {15.7,      0.8,    6.9,    14.65,      5.5,        3.5,    14  },
    };
 
    list<Paquete_de_datos> Tabla;
    tablaLista(Tabla, arrayHoras);
    Tabla.sort(mayorNúmeros);
    mostrar(Tabla);
 
    return 0;
}

Con esto resuelvo el problema y todo parece que funciona bien (con dos observaciones: 1. el vector sería mejor que list y 2. pasar un argumento a sort() es algo raro.), pero lo que continua molestándome es que hasta ahora no he entiendo tus consejos.
Por eso, si no es de pedir demasiado, necesito algunas pistas o ejemplos sobre ellos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar