Programación C++: Vectores, Listas o Arrays: ¿Cómo usarlos?


Los Vectores son listas que almacenan datos, o información sobre una clase en particular. Si tenemos un enunciado, podemos identificarlos de acuerdo al uso de los datos que nos dicen dentro del mismo; ejemplo: se necesita una lista de alumnos, clientes, pacientes; una lista con los números de cédula o pasaporte de los clientes de una aerolínea, quienes cancelaron mas del monto promedio, cuáles alumnos quedaron aplazados en una sección. En fin, tienen muchos usos y utilidad los vectores como parte de C++. 

A continuación veremos unos métodos dado un ejercicio los cuáles nos guiarán sobre el uso de los vectores. 



Cabe destacar, que la metodología que utilizaremos es la programación orientada a objetos. Hemos programado la clase MPaciente, MClinica, VClinica, Controlador y Principal. En la clase MPaciente, hemos programado los datos del paciente: motivo de la visita, turno, y monto cancelado; de la manera usual, para crear una clase, con los respectivos sets y gets. No hay cálculos en esta clase.
/*
 * MPaciente.cpp
 *
 *  Created on: 28/01/2014
 *      Author: Violeta
 */

#include "MPaciente.h"


MPaciente::MPaciente() {


}

float MPaciente::GetMonto()
{
return monto;
}



int MPaciente::GetMotivo()
{
return motivo;
}



int MPaciente::GetTurno()
{
return turno;
}



void MPaciente::SetMonto(float mto)
{
monto = mto;
}



void MPaciente::SetMotivo(int mvo)
{
motivo = mvo;
}



void MPaciente::SetTurno(int t)
{
turno = t;
}

Debemos recordar, que los datos nombre y cédula se heredan de la clase MPersona.
Ahora en MClinica incluimos a la clase paciente como un vector, pues en las salidas nos piden un listado de paciente por consulta, dónde utilizaremos los métodos de incluir, buscar y size: acá veamos cómo queda:

/*
 * MClinica.cpp
 *
 *  Created on: 28/01/2014
 *      Author: Violeta
 */

#include "MClinica.h"

MClinica::MClinica() {
// TODO Auto-generated constructor stub

}

void MClinica::IncluirPaciente(MPaciente mpc)
{
vectpac.push_back(mpc);
}


int MClinica::CantidadPaciente()
{
return vectpac.size();
}



int MClinica::BuscarPaciente(string ced)
{
for (int i=0; i<CantidadPaciente(); ++i)
if (ced== vectpac[i].GetCedula())
return i;
return -1;
}



void MClinica::SetPaciente(MPaciente mpc, int posicion)
{
vectpac[posicion] = mpc;
}



MPaciente MClinica::GetPaciente(int posicion)
{
return vectpac[posicion];
}


Ahora para dar respuesta a la cantidad de pacientes atendidos por turnos, haremos los siguientes métodos:

int MClinica::ContPcTurno(int turn) //este método calcula la cantidad de pacientes atendidos de acuerdo al                                                         //turno que le estemos pidiendo al programa.
{
int cont=0;  //inicializamos el contador en cero
 for (int i=0; i < CantidadPaciente();++i) //para todos los pacientes atendidos
   if (vectpac[i].GetTurno()==turn) //si el turno es igual al ingresado
     ++cont; //cuenta el paciente
 return cont;
}


Para saber cuál fue el monto recolectado por consulta o por hospitalización sólo debemos acumular el monto sólo si el motivo fue consulta o hospitalización respectivamente:

float MClinica::CalcMTConsulta()
{
float acc=0; //inicializamos el acumulador en cero
for (int i=0; i<CantidadPaciente();++i) //para todos los pacientes atendidos
   if (vectpac[i].GetMotivo()==1) //si el motivo fue consulta
    acc+=vectpac[i].GetMonto(); //acumula el monto cobrado
return acc;
}

Como necesitamos saber cuál fue el mayor monto cobrado en las consultas y que nos muestre un listado de las cédulas que pagaron dicho monto, haremos dos métodos: el primero que calcule el mayor monto cobrado y el segundo que haga una comparación y guarde las cédulas que cancelaron dicho monto.

float MClinica::CalcMayor()
{
float mayor=0;
for (int i=0; i<CantidadPaciente();++i)
 if (vectpac[i].GetMotivo()==1 and vectpac[i].GetMonto()> mayor)
mayor=vectpac[i].GetMonto();
return mayor;
}

vector<string> MClinica::vectmayor()
{

float m= CalcMayor();
vector<string> vectmayor;
for (int i=0; i<CantidadPaciente();++i)
 if (vectpac[i].GetMotivo()==1 and vectpac[i].GetMonto()== m)
   vectmayor.push_back(vectpac[i].GetCedula());
    return vectmayor;
}

Ahora bien, hasta este momento estamos listos con respecto a los requerimientos de la práctica, pero ¿cómo haríamos si nos piden el monto promedio cobrado en relación a todos los pacientes atendidos? Debemos crear un acumulador que guarde todos los montos cobrados y los divida entre el size del vector de los pacientes, ya que el size nos da la cantidad de pacientes atendidos en total. Recordar que se debe validar que no exista la división entre cero puesto que nos daría un error.

float MClinica::CalcPromedio()
{
float acumtotal=0; //inicializamos el acumulador en cero
for (int i=0; i < CantidadPaciente(); i++) //para todos los pacientes
acumtotal += vectpac[i].GetMonto(); //acumula el monto cobrado
if (CantidadPaciente()!=0) //si existen pacientes
return acumtotal/CantidadPaciente(); //divide el monto acumulado entre pacientes atendidos
else return 0;
}

Y si nos pidieran: ¿cual es el porcentaje de pacientes que cancelaron un monto mayor al promedio? Puesto que estamos trabajando en base a porcentaje, utilizaremos el método anterior para apoyarnos en la resolución de éste. Siempre verificando que la división no sea entre cero. Utilizaremos un contador de pacientes que cancelaron mas del monto promedio y lo multiplicamos por cien dado que es un porcentaje, para luego dividirlo entre la cantidad de pacientes atendidos, por medio del uso del size.


float MClinica::CalcPorcentaje()
{
int cont = 0; //inicializamos el contador en cero
float prom = CalcPromedio(); //creamos una variable que contenga el monto promedio
for (int i=0; i < CantidadPaciente(); i++) //para todos los pacientes atendidos
if (vectpac[i].GetMonto() > prom) //si el monto es mayor al promedio
cont++; //cuentalo
if (CantidadPaciente()!=0) //si la cantidad de pacientes es distinta de cero
return cont * 100/CantidadPaciente(); //calcula el promedio
else return 0;
}

Si quisiéramos comparar cuál fue el motivo (consulta o hospitalización) con mayor monto recaudado, debemos crear un método que guarde los montos de hospitalización (puesto que ya está hecho el método de consulta) y luego otro método que compare ambos montos y retorne un string con la respuesta; tomando en cuenta que puede ser iguales los montos obtenidos.

float MClinica::CalcMayorHospitalizacion()
{
float mayorhosp=0;
for (int i=0; i<CantidadPaciente();++i)
 if (vectpac[i].GetMotivo()==2 and vectpac[i].GetMonto()> mayorhosp)
mayorhosp=vectpac[i].GetMonto();
return mayorhosp;
}


string MClinica::CalcMayorTurno()
{
if (CalcMayor() < CalcMayorHospitalizacion())
return "Hospitalizacion";
if (CalcMayor() > CalcMayorHospitalizacion())
return "Consulta";
else return "Consulta y Hospitalizacion";

}

Si quieren ver cómo funcionan todos los métodos ensamblados aquí les dejo:

El programa con los requerimientos netos de la práctica: Clinica
El programa con las sugerencias adicionales: Clinica con Requerimientos

Si quieren ver vídeos sobre el uso de vectores pueden ver la lista de reproducción que he creado en youtube: C++ Vectores ojo, esta lista no contiene información orientada a objetos.

Éxitos!


Comentarios