2. [TD]: El problema
Palabras clave: algoritmos, conceptos básicos de Java: matrices, E/S, bucles, comprobaciones, gestión 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 explica el método de cálculo de escaños para unas elecciones proporcionales por la media más alta, tal y como se describe 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 utilice el teclado y la pantalla para comunicarse con el usuario. La aplicación solicitará al usuario la siguiente información (introducida mediante el teclado):
- número de escaños a cubrir
- número de listas que se presentan
- para cada lista: su nombre y su número de votos
Con estos datos, la aplicación calcula los escaños obtenidos por cada una de las listas y los muestra en pantalla de la siguiente forma:
donde [Xi] es el nombre de la lista n.º i y [Ni] el número de escaños que ha obtenido.
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 escaños por cubrir
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 liza
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
// dimensión de las mesas electorales
dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments
// introducción de los nombres y votos de las listas
totalVoix<-0
pour i variant de 0 à nbListes-1
// introducción 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
// introducción 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 un escaño en cada ronda del bucle
pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
// búsqueda de la lista con la media más alta
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 la media más alta
siegeListe[iMax] <- siegeListe[iMax]+1
// y se modifica su media
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 pendiente
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 incluirá en un paquete, en este caso [istia.st.elections]
- [3]: [MainElections.java] es el código fuente de la aplicación escrita en la parte anterior
- [4]: se ejecuta la clase [MainElections]
Un ejemplo de ejecución podría ser el siguiente:
