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:
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.:


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:
