Skip to content

2. [TD]: Problem

Słowa kluczowe: algorytmy, podstawy języka Java: tablice, operacje wejścia/wyjścia, pętle, testy, obsługa wyjątków

Zalecana lektura: rozdział 1 z [ref1]: Podstawy języka Java

2.1. Support

  

Folder [support / chap-02] zawiera algorytm do przełożenia na języki C# i Java.

2.2. Problem do rozwiązania

Chcemy napisać program, który w wieczór wyborczy będzie w stanie obliczyć liczbę mandatów zdobytych przez poszczególne listy wyborcze. Nieco dalej przedstawiono sposób obliczania mandatów w wyborach proporcjonalnych metodą najwyższej średniej, zgodnie z wyjaśnieniem zawartym w artykule z gazety „Ouest-France” z 15 marca 1986 r.

Napiszemy konsolową aplikację Java o nazwie „c.a.d” – aplikację wykorzystującą klawiaturę i ekran do komunikacji z użytkownikiem. Aplikacja poprosi użytkownika o podanie następujących informacji (wpisywanych za pomocą klawiatury):

  • liczba mandatów do obsadzenia
  • liczba list startujących w wyborach
  • dla każdej listy: jej nazwę oraz liczbę uzyskanych głosów

Na podstawie tych danych aplikacja oblicza liczbę mandatów uzyskanych przez każdą z list i wyświetla je na ekranie w następującej formie:

  • Lista [X1] zdobyła [N1] mandatów

  • Lista [X2] uzyskała [N2] mandatów

  • ...

gdzie [Xi] to nazwa listy nr i, a [Ni] to liczba mandatów, które ta lista uzyskała.

Artykuł z gazety „Ouest-France” z 15 marca 1986 r.:

Image

Image

2.3. Rozwiązanie algorytmiczne

Rozwiązanie algorytmiczne mogłoby wyglądać następująco:

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

     // kod
     // liczba miejsc do obsadzenia
    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
     // liczba list startujących w wyborach
    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

     // wielkość tabel
    dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments

     // wprowadzanie nazw i głosów list
    totalVoix<-0
    pour i variant de 0 à nbListes-1
         // wprowadzanie nazwy listy 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
     // wprowadzanie liczby głosów listy 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

     // zwiększamy sumę głosów
    totalVoix<- totalVoix+voixListe[i]79.finpour 80.
     // obliczanie głosów ważnych
    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
     // czy są listy, które nie zostały wyeliminowane?
    si nbVoixUtiles=0 alors
        écrire "Erreur : toutes les listes ont été éliminées"
        arrêt du programme
    finsi
     // podział mandatów według ilorazu
    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
     // podział pozostałych mandatów według najwyższej średniej
     // w każdej pętli przyznawany jest 1 mandat
    pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
         // wyszukiwanie listy o najwyższej średniej
        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
         // przyznaje się 1 mandat liście o najwyższej średniej
        siegeListe[iMax] <- siegeListe[iMax]+1
         // i zmienia się jej średnia
        moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
    finpour
     // wyświetlanie wyników bez sortowania
    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. Zadanie do wykonania

Q1: przełożyć algorytm na język C#. Zaimplementować go w programie Visual Studio.

Q2: przełożyć algorytm na język Java, czerpiąc inspirację z kodu w języku C#. Zaimplementować program w języku Java w środowisku Eclipse podobnym do poniższego:

  • [1]: projekt nosi nazwę [elections-01]
  • [2]: aplikacja zostanie umieszczona w pakiecie, w tym przypadku [istia.st.elections]
  • [3]: [MainElections.java] to kod źródłowy aplikacji napisanej w poprzedniej części
  • [4]: klasa [MainElections] jest uruchamiana

Przykładowe wykonanie mogłoby wyglądać następująco:

Image