2. [Trabalho]: O Problema
Palavras-chave: algoritmos, noções básicas de Java: matrizes, E/S, loops, testes, tratamento de exceções
Leitura recomendada: Capítulo 1 de [ref1]: Os Fundamentos da Linguagem Java
2.1. Suporte
A pasta [support / chap-02] contém o algoritmo a ser implementado em C# e Java.
2.2. O problema a resolver
Queremos escrever um programa que, na noite das eleições, consiga calcular o número de lugares conquistados pelas várias listas de candidatos. Mais adiante, encontraremos o método para calcular os lugares numa eleição por representação proporcional utilizando a média mais elevada, tal como explicado num artigo do jornal Ouest-France de 15 de março de 1986.
Iremos escrever uma aplicação Java de «console», ou seja, uma aplicação que utiliza o teclado e o ecrã para interagir com o utilizador. A aplicação solicitará ao utilizador as seguintes informações (introduzidas através do teclado):
- número de lugares a preencher
- número de listas concorrentes
- para cada lista: o seu nome e número de votos
Com base nestas informações, a aplicação calcula o número de lugares conquistados por cada lista e apresenta-os no ecrã no seguinte formato:
onde [Xi] é o nome da lista n.º i e [Ni] é o número de lugares que conquistou.
Artigo do Ouest-France de 15 de março de 1986:


2.3. A solução algorítmica
Uma solução algorítmica poderia ser a seguinte:
| début-programme
// données
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
// code
// nbre de sièges à pourvoir
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de sièges à pourvoir : "
lire nbSiègesAPourvoir
si nbSiègesAPourvoir n'is not an integer >0 then
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// nbre de listes en compétition
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de listes en compétition : "
lire nbListes
si nbListes n'is not an integer >0 then
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// dimensionnement des tableaux
dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments
// saisie des noms et voix des listes
totalVoix<-0
pour i variant de 0 à nbListes-1
// saisie du nom de la liste 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
// saisie du nombre de voix de la liste i
saisieOK<-faux
tantque non saisieOK
écrire "Nombre de voix de la liste ", nomListe[i] , " : "
lire voixListe[i]
si voixListe[i] n'is not an integer >=0 then
écrire "Erreur : tapez un nombre entier >=0"
sinon
saisieOK<-vrai
finsi
fintantque
// on incrémente le total des voix
totalVoix<- totalVoix+voixListe[i]79.finpour 80.
// calcul des voix utiles
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
// y-a-t-il des listes non éliminées ?
si nbVoixUtiles=0 alors
écrire "Erreur : toutes les listes ont été éliminées"
arrêt du programme
finsi
// répartition des sièges au quotient
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
// répartition des sièges restants à la plus forte moyenne
// 1 siège est attribué à chaque tour de boucle
pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
// recherche de la liste ayant la + forte moyenne
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
// on attribue 1 siège à la liste de + forte moyenne
siegeListe[iMax] <- siegeListe[iMax]+1
// et on change sa moyenne
moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
finpour
// affichage résultats sans tri
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. Trabalho a realizar
Q1: Traduzir o algoritmo para C#. Implementá-lo utilizando o Visual Studio.
Q2: Traduzir o algoritmo para Java, inspirando-se no código C#. Implementar o programa Java num ambiente Eclipse semelhante ao seguinte:
- [1]: O projeto tem o nome [elections-01]
- [2]: A aplicação será colocada num pacote, neste caso [istia.st.elections]
- [3]: [MainElections.java] é o código-fonte da aplicação escrita na secção anterior
- [4]: a classe [MainElections] é executada
Um exemplo de execução poderia ser o seguinte:
