2. [作业]:问题
关键词:算法,Java基础:数组、I/O、循环、测试、异常处理
推荐阅读:[ref1] 第1章:《Java语言基础》
2.1. 支持
文件夹 [support / chap-02] 包含需用 C# 和 Java 实现的算法。
2.2. 待解决的问题
我们要编写一个程序,使其能在选举之夜计算出各候选人名单所获得的席位数。接下来,我们将介绍一种计算比例代表制选举中席位的方法,该方法采用最高平均值法,正如1986年3月15日《法国西部报》的一篇文章中所阐述的那样。
我们将编写一个 Java “控制台”应用程序,即通过键盘和屏幕与用户交互的应用程序。该程序将要求用户输入以下信息(通过键盘输入):
- 待填补的席位数
- 参选名单数量
- 对于每个候选名单:其名称和得票数
应用程序利用这些信息计算出每个候选名单赢得的席位数,并以以下格式在屏幕上显示:
-
名单 [X1] 赢得 [N1] 个席位
-
名单 [X2] 赢得 [N2] 个席位
-
...
其中 [Xi] 表示第 i 号名单的名称,[Ni] 表示其赢得的席位数。
1986年3月15日《西法兰西报》的报道:


2.3. 算法解决方案
算法解决方案可能如下:
| 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. 待完成的工作
Q1:将该算法转换为 C# 代码。使用 Visual Studio 实现该算法。
Q2:参考 C# 代码,将该算法转换为 Java 语言。在 Eclipse 环境中实现 Java 程序,示例如下:
- [1]: 项目名称为 [elections-01]
- [2]: 该应用程序将放置在一个包中,此处为 [istia.st.elections]
- [3]: [MainElections.java] 是上一节中编写的应用程序的源代码
- [4]: 执行 [MainElections] 类
执行示例如下:
