Skip to content

2. [TD]: Проблема

Ключові слова: алгоритміка, основи Java: масиви, введення-виведення, цикли, перевірки, обробка винятків

Рекомендована література: розділ 1 з [ref1]: Основи мови Java

2.1. Support

  

Папка [support / chap-02] містить алгоритм, який потрібно перекласти на C# та Java.

2.2. Задача, яку потрібно вирішити

Потрібно написати програму, яка ввечері в день виборів зможе підрахувати кількість місць, отриманих різними списками-учасниками. Трохи далі наведено спосіб підрахунку місць для пропорційних виборів за принципом «найвищого середнього», як це пояснено у статті газети «Ouest-France» від 15 березня 1986 року.

Ми напишемо консольну програму на Java, c.a.d — програму, яка використовує клавіатуру та екран для взаємодії з користувачем. Вона запитає у користувача наступну інформацію (введену з клавіатури):

  • кількість місць, що підлягають заповненню
  • кількість списків-учасників
  • для кожного списку: його назву та кількість голосів

На основі цих даних програма обчислює кількість місць, отриманих кожним зі списків, і відображає їх на екрані у такому вигляді:

  • Список [X1] отримав [N1] місць

  • Список [X2] отримав [N2] місць

  • ...

де [Xi] — назва списку № i, а [Ni] — кількість місць, яку він отримав.

Стаття в газеті «Ouest-France» від 15 березня 1986 року:

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: переписати алгоритм на Java, спираючись на код на C#. Реалізувати програму на Java в середовищі Eclipse, аналогічному наведеному нижче:

  • [1]: проект називається [elections-01]
  • [2]: додаток буде розміщено в пакеті, у даному випадку [istia.st.elections]
  • [3]: [MainElections.java] — це вихідний код програми, написаної в попередньому розділі
  • [4]: виконується клас [MainElections]

Приклад виконання може виглядати так:

Image