【问题标题】:Method is not returning correct answer?Does anyone have anymore input?方法没有返回正确的答案?还有人输入吗?
【发布时间】:2015-02-03 19:53:16
【问题描述】:

在这种方法中,我应该返回选举的获胜者。这是通过重复使用candidatesWithFewest() 方法来完成的,直到只有一个候选人(得票最多)。您通过成为选票上的名字获得选票。如果两名或多名候选人获得相同数量的第一名选票,则选举不是决定性的。我的错误是,当两个或多个候选人拥有相同数量的第一名选票时,它仍然会返回其中一个候选人。我所有的其他方法都返回正确的输出,所以我相信问题出在getWinner 方法中。 CandidateWithFewest 返回所有得票最少的候选人的列表。我想从名单中删除这些候选人,直到只剩下一名候选人。

    /**
    * 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
}
}

【问题讨论】:

  • 需要更多细节吗?
  • 你可能只想要candList.remove(s) 我认为因为你一直将失败者附加到listString 上,这可能不是你想要删除的失败者的名字,它会是所有的名字,因此candList.remove 会失败
  • 不应该是candList.remove(listString);candList.remove(s);
  • losers = new ArrayList&lt;String&gt;(); // adds loser to list 代码与评论不符,你确定这是你想做的吗?
  • 如果我这样做 candList.remove(s) 我总是得到“选举不是决定性的”。

标签: java


【解决方案1】:

我猜是代码 sn-p :

for (String s : loser) {
            listString += s;
            candList.remove(listString);         
        } 

正在为您制造问题,因为它仅适用于首次运行;对于其余 (n-1) 次运行,它不会删除任何内容!

我不明白您为什么要将候选名称加入 listString 变量? 如果您需要删除单个候选名称,那么以下应该是正确的方法:

for (String s : loser) {
            //listString += s;
            candList.remove(s);         
        } 

有意义吗?

【讨论】:

  • 如果我这样做,我总是会得到“选举不是决定性的”。我不知道为什么。
  • 您需要检查两件事 - 首先:检查此代码 sn-p :code if (votes (); // 将失败者添加到列表 // 将此候选人也添加到 losres 列表中 losters.add(candidateList.get(can));第二:仔细检查这个方法 bold numFirstVotes(candidate, CandidateList);是否返回正确的东西?
【解决方案2】:

这是一个建议。不喜欢就离开吧!

解决此类问题的更清晰的方法是使用带有 候选人姓名将是关键,值是投票数。 当你遍历投票列表时,检查候选人的名字是否存在于地图中,如果存在,只需增加计数,否则将其设置为 1(这意味着你看到的第一个投票)

【讨论】:

    【解决方案3】:

    我认为您的代码有很多问题可能会导致问题。

    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 的设置方式,因此很难同意您认为该代码有效。您的 cmets 不反映代码在做什么,应该删除或更新。

    我认为真正的问题在这里

    while (candList.size() > 2)
    

    这就是说,循环直到列表中有 2 个或更少的项目。它不会说循环,直到列表中有 1 个或更少的项目,这基于你的 cmets 是你想要它做的。 因此,如果没有您的其余代码来测试我的猜测,我无法确定,但我认为您想将循环条件更改为

    while (candList.size() >= 1)
    

    如果更改后仍然无法正常工作,那么您的代码中可能还有更多问题,例如上面的 for 循环和 numFirstVotes 方法。

    【讨论】:

    • 我认为我的问题是您与 joe john 和 dave 一起使用的示例。有没有办法将每个名称分开并删除它们。
    • 我很确定它会是&gt; 1而不是&gt;= 1
    • @chancea 你知道如何像他在示例中展示的那样分隔名字 joe john 和 dave 并从列表中删除每个名字。
    • @Name 这就是我们所说的candList.Remove(s)
    • 我知道我试过 candList.remove(s)。而且每次它给我的选举都不是决定性的。我的 if else 语句会不会有问题。
    【解决方案4】:

    我会对你的代码做一些小的修改。您可以直接从该方法返回获胜者,而不是返回失败者并迭代地删除它们。基本上,您通过在每次迭代中删除最小元素来找到最大元素。这不是你应该接近的方式。

    更改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.";
        }
    }
    

    【讨论】:

    • 感谢您的帮助。是的,我更喜欢你的方式。但我必须使用 CandidateWithFewest 方法。
    • @Name 这很奇怪。在这种情况下,您的代码对我来说似乎很好。要么你在某个地方做其他事情,我们不知道。你能发布你的numFirstVotes 方法吗?
    【解决方案5】:

    尝试使用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
    }
    

    【讨论】:

    • 如果我这样做,我总是会得到“选举不是决定性的”
    • 在这种情况下,请查看返回失败者的方法......当您必须删除候选人时,您应该删除该候选人而不是将其添加到列表中并且删除所有内容
    • 问题是返回失败者的方法返回一个列表。而且我必须从失败者列表中提取每个字符串并将其删除。
    • 请检查我的答案...已经进行了一些编辑。另外,我知道它返回一个列表,但是您使用的是 foreach 循环。因此,该列表的所有元素都将被获取,您可以将它们一一删除......尝试使用带有虚拟样本的笔和纸。你会明白我确定
    • if(votes == minTally) 这一行仅在执行前面的 if 语句时才为真。有可能会跳过前面的 if 语句,但仍然可以执行此语句。这完全取决于数据以及 numFirstVotes 的工作方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多