2. [TD]: El problema
Palabras clave: algoritmos, conceptos básicos de Java: matrices, E/S, bucles, pruebas, manejo de excepciones
Lecturas recomendadas: capítulo 1 de [ref1]: Fundamentos del lenguaje Java
2.1. Support
El archivo [support / chap-02] contiene el algoritmo que hay que traducir a C# y Java.
2.2. El problema a resolver
Se desea escribir un programa que, la noche de las elecciones, pueda calcular el número de escaños obtenidos por las diferentes listas participantes. Más adelante se explicará el método de cálculo de escaños para una elección proporcional por la media más alta, tal como se explica en un artículo del periódico Ouest-France del 15 de marzo de 1986.
Escribiremos una aplicación Java de «consola», c.a.d, que utiliza el teclado y la pantalla para comunicarse con el usuario. La aplicación solicitará al usuario la siguiente información (ingresada mediante el teclado):
- número de escaños a cubrir
- número de listas en contienda
- para cada lista: su nombre y su número de votos
Con esta información, la aplicación calcula los escaños obtenidos por cada una de las listas y los muestra en pantalla de la siguiente manera:
donde [Xi] es el nombre de la lista n.º i y [Ni] el número de escaños que obtuvo.
El artículo de Ouest-France del 15 de marzo de 1986:


2.3. La solución algorítmica
Una solución algorítmica podría ser la siguiente:
| début-programme
// datos
saisieOK : booléen
nbSiègesAPourvoir : entier
nbListes : entier
nomListe[] : chaînes de caractères
voixListe[] : entier
elimineListe[] : booléen
siegesListe[] : entier
moyenneListe[] : réel
i : entier
nbVoixUtiles : entier
quotientElectoral : réel
nbSiègesPourvus : entier
moyenneMax : réel
Max : entier iSiège : entier
// código
// número de puestos vacantes
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de sièges à pourvoir : "
lire nbSiègesAPourvoir
si nbSiègesAPourvoir n'est pas un entier >0 alors
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// número de listas en competencia
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de listes en compétition : "
lire nbListes
si nbListes n'est pas un entier >0 alors
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// tamaño de las tablas
dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments
// ingreso de los nombres y votos de las listas
totalVoix<-0
pour i variant de 0 à nbListes-1
// ingreso del nombre de la lista i
saisieOK<-faux
tantque non saisieOK
écrire "Nom de la liste n° ", i, " : "
lire nomListe[i]
si nomListe[i] est vide alors
écrire "Erreur : Tapez un nom non vide"
sinon
saisieOK<-vrai
finsi
fintantque
// ingreso del número de votos de la lista i
saisieOK<-faux
tantque non saisieOK
écrire "Nombre de voix de la liste ", nomListe[i] , " : "
lire voixListe[i]
si voixListe[i] n'est pas un nombre entier >=0 alors
écrire "Erreur : tapez un nombre entier >=0"
sinon
saisieOK<-vrai
finsi
fintantque
// se incrementa el total de votos
totalVoix<- totalVoix+voixListe[i]79.finpour 80.
// cálculo de los votos válidos
nbVoixUtiles<-0
pour i variant de 0 à nbListes-1
si (voixListe[i]/totalVoix)<0.05 alors
elimineListe[i]<-vrai
sinon
elimineListe[i]<-faux
nbVoixUtiles<-nbVoixUtiles+voixListe[i]
finsi
finpour
// ¿Hay alguna lista que no haya sido eliminada?
si nbVoixUtiles=0 alors
écrire "Erreur : toutes les listes ont été éliminées"
arrêt du programme
finsi
// distribución de escaños por cociente
quotientElectoral <- nbVoixUtiles / nbSiègesAPourvoir
nbSiègesPourvus<- 0
pour i variant de 0 à nbListes-1
si non elimineListe[i] alors
siegesListe[i]<- partie entière de (voixListe[i]/quotientElectoral)
moyenneListe[i] <- voixListe[i] / (siegesListe[i]+1)
nbSiègesPourvus<-nbSiègesPourvus+siegesListe[i]
sinon
siegesListe[i]<-0
finsi
finpour
// distribución de los escaños restantes por la media más alta
// Se asigna 1 escaño en cada ronda del ciclo
pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
// búsqueda de la lista con el promedio más alto
moyenneMax<- (-1)
pour i variant de 0 à nbListes-1
si non elimineListe[i] alors
si moyenneListe[i] > moyenneMax alors
moyenneMax <- moyenneListe[i]
iMax <- i
finsi
finsi
finpour
// se asigna 1 escaño a la lista con el promedio más alto
siegeListe[iMax] <- siegeListe[iMax]+1
// y se modifica su promedio
moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
finpour
// visualización de los resultados sin ordenar
pour i variant de 0 à nbListes-1
si elimineListe[i] alors
écrire "La liste ", nomListe[i], " a été éliminée"
sinon
écrire "La liste ", nomListe[i], " a obtenu ",
siegesListe[i], " siège(s)"
finsi
finpour
fin-programme
|
2.4. Tarea a realizar
Q1: traducir el algoritmo a C#. Implementarlo con Visual Studio.
Q2: traducir el algoritmo a Java inspirándote en el código de C#. Implementar el programa Java en un entorno Eclipse similar al siguiente:
- [1]: el proyecto se llama [elections-01]
- [2]: la aplicación se colocará en un paquete, en este caso [istia.st.elections]
- [3]: [MainElections.java] es el código fuente de la aplicación escrita en la sección anterior
- [4]: se ejecuta la clase [MainElections]
Un ejemplo de ejecución podría ser el siguiente:
