Skip to content

2. [TD]:问题

关键词:算法,Java基础:数组、I/O、循环、条件判断、异常处理

推荐阅读:[ref1] 第1章:Java语言基础

2.1. Support

  

文件 [support / chap-02] 包含需转换为 C# 和 Java 的算法。

2.2. 待解决的问题

我们希望编写一个程序,在选举当晚能够计算出各参选名单所获得的席位数。稍后将介绍最高平均数比例代表制选举的席位计算方法,该方法在1986年3月15日《西法兰西报》的一篇文章中有过说明。

我们将编写一个Java“控制台”应用程序c.a.d,该应用程序通过键盘屏幕与用户交互。它将要求用户输入以下信息(通过键盘输入):

  • 待选席位数
  • 参选名单数量
  • 每个候选名单:名称、得票数

基于这些信息,该应用程序将计算各候选名单获得的席位数,并以如下形式显示在屏幕上

  • 候选名单 [X1] 获得 [N1] 个席位

  • 候选名单 [X2] 获得 [N2] 个席位

  • ...

其中 [Xi] 是第 i 号名单的名称,[Ni] 是该名单获得的席位数。

1986年3月15日《西法兰西报》报道:

Image

Image

2.3. 算法解决方案

一种算法解决方案可能如下:

début-programme
     // 数据
    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

     // 代码
     // 待填补席位数
    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
     // 参选名单数量
    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

     // 表格尺寸
    dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments

     // 候选名单名称及得票数录入
    totalVoix<-0
    pour i variant de 0 à nbListes-1
         // 候选名单 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
     // 输入候选名单 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

     // 增加总票数
    totalVoix<- totalVoix+voixListe[i]79.finpour 80.
     // 计算有效票数
    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
     // 是否有未被淘汰的名单?
    si nbVoixUtiles=0 alors
        écrire "Erreur : toutes les listes ont été éliminées"
        arrêt du programme
    finsi
     // 按商数分配席位
    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
     // 按最高平均票数分配剩余席位
     // 每轮循环分配 1 个席位
    pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
         // 查找平均分最高的名单
        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
         // 将1个席位分配给平均分最高的名单
        siegeListe[iMax] <- siegeListe[iMax]+1
         // 并更新其平均分
        moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
    finpour
     // 显示未排序的结果
    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]

一个执行示例如下:

Image