В этом методе я должен вернуть победителя на выборах. Это делается путем многократного использования метода requestsWithFewest candidatesWithFewest()
пока не будет только один кандидат (на который больше всего голосов). Вы получаете голосование, будучи первым именем в бюллетене. Если два или более кандидатов имеют одинаковое количество голосов в первом месте, то выборы не являются решающими. Моя ошибка заключается в том, что, когда у двух или более кандидатов есть одинаковое количество голосов первого места, они все равно возвращают одного из этих кандидатов. Все мои другие методы возвращают правильный результат, поэтому я считаю, что проблема заключается в методе getWinner
. candidatesWithFewest возвращает список всех кандидатов с наименьшим количеством голосов. Я хочу удалить этих кандидатов из списка, пока не останется только один кандидат.
/**
* Returns the winner of the election using the candidatesWithFewest()
* method.If there is no winner method returns a statement stating the
* election is not decisive.
*
* @param vbal VoterBallots object
* @param candList a list of candidate names
* @return the winner of the election
*/
public String getWinner(VoterBallots vbal, ArrayList<String> candList) {
// Run rounds until down to a single candidate
while (candList.size() > 2) {
ArrayList<String> loser = vbal.candidatesWithFewest(candList);
String listString = "";
for (String s : loser) {
listString += s;
candList.remove(listString);
}
}
if (candList.size() > 0) {
return candList.iterator().next(); // Return the surviving candidate
} else {
return "Election is non decisive.";
}
}
/**
* Returns a list of one or more candidates tied with the fewest
* first choice votes
*
* Precondition: each String in candidateList appears exactly once
* in each Ballot in ballotList
*
* @param candidateList a list of candidate names
*
* @return a list of those candidates tied with the fewest first
* choice votes
*/
public ArrayList<String> candidatesWithFewest(ArrayList<String> candidateList) {
ArrayList<String> losers = new ArrayList<String>(); //empty list for losers
int minTally = ballotList.size() + 1; //number of min votes
for (int can = 0; can < candidateList.size(); can++) {
String candidate = candidateList.get(can);
// // number of first place votes
int votes = numFirstVotes(candidate, candidateList);
if (votes < minTally) {
minTally = votes;
losers = new ArrayList<String>(); // adds loser to list
}
if (votes == minTally) {
losers.add(candidateList.get(can)); //adds losers with the same vote
}
}
return losers; // returns list of candidates with fewest votes
}
/**
* Returns the number of times a given candidate appears first, among those
* elements that are on candidateList, among all elements of ballotList
* (i.e., among all ballots)
*
* @param candidate the name of a candidate
* @param candidateList a list of candidate names Precondition: candidate
* appears in candidateList
* @return the number of times that candidate is first among those in
* candidateList for all elements of ballotList
*/
public int numFirstVotes(String candidate, ArrayList<String> candidateList)
// implementation not shown
{
int numVotes = 0;
for (Ballot voterBallot : ballotList) {
String first = voterBallot.firstChoiceFrom(candidateList);
if (candidate.equals(first)) {
numVotes++;
}
}
return numVotes;
}
/**
* @param candidateList a list of candidate names
* @return the name of the first choice candidate for this Ballot from those
* in candidateList
*/
public String firstChoiceFrom(ArrayList<String> candidateList) {
for (String firstChoice : ballot) {
if(candidateList.contains(firstChoice))
{
return firstChoice;
}
}
return null; // does not appear on candidate list
}
}
это предложение. Если вам это не нравится, оставьте это!
Более четким способом решения этой проблемы будет использование хэш-карты с именем кандидата, которое будет ключевым, а значение - количеством голосов. Когда вы перебираете список голосов, проверьте, существует ли имя кандидата на карте, если это так, просто увеличивайте счетчик, иначе установите его на 1 (что означает первый голос, который вы видите)
Я думаю, фрагмент кода:
for (String s : loser) {
listString += s;
candList.remove(listString);
}
создает проблему для вас, потому что она будет работать нормально только для первого запуска; для остальных (n-1) бежит он ничего не удалит!
Я не могу понять, почему вы присоединяете имена кандидатов в переменную listString? Если вам нужно удалить одно имя кандидата, то следующее должно быть правильным:
for (String s : loser) {
//listString += s;
candList.remove(s);
}
имеет смысл?
code
: code
if (голоса <minTally) {minTally = голоса; lostrs = new ArrayList <String> (); // добавляем проигравшего в список // Добавляем этого кандидата в список losres тоже lostrs.add (кандидатList.get (can)); } Второе: дважды проверьте этот метод bold numFirstVotes (андидат, кандидатList); возвращает ли это правильную вещь?
Я бы сделал небольшую модификацию вашего кода. Вместо того, чтобы возвращать проигравших и удалять их итеративно, вы можете напрямую вернуть победителей из этого метода. В основном вы находите элемент max, удаляя min-элемент на каждой итерации. Это не то, как вы должны приближаться.
Измените candidatesWithFewest
наивысшими candidatesWithHighest
методаВ самом большом и измените логику соответственно:
public ArrayList<String> candidatesWithHighest(ArrayList<String> candidateList) {
ArrayList<String> winners = new ArrayList<String>(); //empty list for losers
int maxTally = ballotList.size() + 1; //number of min votes
for (int can = 0; can < candidateList.size(); can++) {
String candidate = candidateList.get(can);
// // number of first place votes
int votes = numFirstVotes(candidate, candidateList);
if (votes > maxTally) {
maxTally = votes;
winners = new ArrayList<String>(); // Reset the list
} else if (votes == maxTally) {
winners.add(candidateList.get(can)); //adds winners with the same vote
}
}
return winners; // returns list of candidates with highest votes
}
И тогда ваш первый метод не требует какого - либо while
цикл вообще. Просто получите список, проверьте размер. Если он больше 1, то пропустите ошибку:
public String getWinner(VoterBallots vbal, ArrayList<String> candList) {
ArrayList<String> winners = vbal.candidatesWithHighest(candList);
if (candList.size() < 2) {
return candList.iterator().next(); // Return the surviving candidate
} else {
return "Election is non decisive.";
}
}
numFirstVotes
?
Я думаю, что есть много проблем с вашим кодом, который может вызвать проблемы.
for (String s : loser)
{
listString += s;
candList.remove(listString);
}
Этот код добавляет каждое имя в список проигравших и пытается удалить его из списка candList, поэтому предположим, что в списке неудач есть [joe, john, dave], тогда этот цикл говорит remove ("joe"), а затем удаляет ( "joejohn"), затем удалите ("joejohndave"). Это действительно то, что вы хотите сделать?
int votes = numFirstVotes(candidate, candidateList);
Здесь могут быть проблемы, поскольку ballotList является глобальным, возможно, вы используете его правильно в этой функции, но поскольку я не вижу код, который я не знаю.
Поскольку у нас нет кода для numFirstVotes или как настраивается ballotList, вам сложно согласиться с тем, что этот код работает. Ваши комментарии не отражают то, что делает код, и должны быть удалены или обновлены.
Я думаю, что настоящая проблема здесь
while (candList.size() > 2)
Это говорит, цикл, пока в списке не будет 2 или меньше элементов. Он не говорит о цикле, пока в списке не будет 1 или меньше элементов, которые на основе ваших комментариев будут тем, что вы хотите. Таким образом, без остальной части кода, чтобы проверить мое предположение, я не могу быть уверен, но я думаю, вы хотите изменить условие цикла на
while (candList.size() >= 1)
Если он по-прежнему не работает после этого изменения, у вас, вероятно, будет больше проблем с вашим кодом, например, цикл for выше и в методе numFirstVotes.
> 1
не >= 1
попробуйте с candList.remove(s);
вместо candList.remove(listString);
Кроме того, по сути, в этом методе есть некоторые проблемы
public ArrayList<String> candidatesWithFewest(ArrayList<String> candidateList) {
ArrayList<String> losers = new ArrayList<String>(); //empty list for losers
int minTally = ballotList.size() + 1;
for (int can = 0; can < candidateList.size(); can++) {
String candidate = candidateList.get(can);
// // number of first place votes
int votes = numFirstVotes(candidate, candidateList);
if (votes < minTally) {
minTally = votes; //.... here you have made minTally == votes
losers = new ArrayList<String>(); // adds loser to list ..... here again you are repeating the first line of this method
}
if (votes == minTally) { //..... this will be true because although originally votes were less than minTally still, your assignment makes them equal
losers.add(candidateList.get(can)); //adds losers with the same vote
}
}
return losers; // returns list of candidates with fewest votes
}
candList.remove(s)
я думаю, потому что вы продолжаетеlistString
проигравших вlistString
который, вероятно, не является именем проигравшего, которого вы хотите удалить, это будут все имена, и, таким образом,candList.remove
потерпит неудачу