以相同的票数输出两名候选人

时间:2017-01-17 13:06:39

标签: c#

对不起作业问题,我知道有些人不喜欢他们,但我不知所措。 我按照我的任务编写了一个代码,让用户输入他们想要投票的人等等,这些都有效。第二部分任务是修改它,如果两个候选人有相同的投票而不是第三个是" ...."在第二个是" ..." (第三名的投票数相同)是#34; ......"它将在第二个输出" ... + ..."在第一个是" ..."

到目前为止,这是我的代码;

class Program
{
    static void Main(string[] args)
    {
        //create empty arrays
        int[] votes = new int[5];
        string[] names = { "Ahmed", "Boo", "Celine", "Didi", "Elaine" };
        for (int i = 0; i < names.Length; i++)
        {
            Console.WriteLine("{0} {1}", i, names[i]);
        }

        //input votes
        Input(votes);

        //sort votes
        Sort(votes, names);

        if (votes[0] > 0)//If there are any votes for the top candidate then do not display the output
        {
            //output sorted data
            Console.WriteLine("\nVote summary");
            Output(votes, names);

            Console.WriteLine("\nIn third place: {0}", names[2]);
            Console.WriteLine("In second place: {0}", names[1]);
            Console.WriteLine("And the winner is: {0}", names[0]);
        }
        else
        {
            Console.WriteLine("No votes were made!");
        }

        Console.ReadLine();
    }//end Main

    static void Input(int[] arr)
    {
        int vote = EnterInt("Enter number of candidate you wish to vote for (0 to 4) or -1 to quit:");

        while (vote != -1)
        {
            if (vote < 0 || vote > 4)
            {
                Console.WriteLine("Invalid vote");
            }
            else
            {
                arr[vote]++;
            }
            vote = EnterInt("Enter number of candidate you wish to vote for (0 to 4) or -1 to quit:");
        }//end while
    }//end InputArray


    public static void Sort(int[] votes, string[] names)
    {
        for (int pass = 1; pass < votes.Length; pass++)
        {
            int smallestPos = FindSmallest(votes, votes.Length - pass);
            if (smallestPos != votes.Length - pass)
            {
                Swap(votes, smallestPos, votes.Length - pass);
                Swap(names, smallestPos, votes.Length - pass);
            }
        }//end for
    }//end Sort

    public static int FindSmallest(int[] votes, int num)
    {
        int smallestPos = 0;
        for (int i = 1; i <= num; i++)
        {
            if (votes[i] < votes[smallestPos])
            {
                smallestPos = i;
            }
        }//end for
        return smallestPos;
    }//end FindSmallest

    public static void Swap(int[] votes, int first, int second)
    {
        int temp = votes[first];
        votes[first] = votes[second];
        votes[second] = temp;
    }//end Swap

    public static void Swap(string[] names, int first, int second)
    {
        string temp = names[first];
        names[first] = names[second];
        names[second] = temp;
    }//end Swap

    public static void Output(int[] votes, string[] names)
    {
        for (int i = 0; i < votes.Length; i++)
        {
            Console.WriteLine("{0} {1}", names[i], votes[i]);
        }//end for
    }//end Output


    static int EnterInt(string prompt)
    {
        Console.Write(prompt);
        int num;
        while (!int.TryParse(Console.ReadLine(), out num))
        {
            Console.Write("Error! Please enter an integer number:");
        }//end while
        return num;
    }
}

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

首先,我建议您使用单一集合来存储所有候选人姓名及其投票数(由评论中的@Sinatr建议),因为它使代码更加简单使用方便的Linq函数,如.OrderBy()。

要实现这一目标,您可以使用许多选项,您可以使用名称投票属性创建自己的候选类,或者您可以使用已经预定义的类型,例如元组(字符串,整数)字典,就像我在示例代码中使用的那样。

正如你所注意到的,这个问题的难点在于以最多票数对三位候选人的投票排名进行排序。我使用的方法是分组候选人相同的投票数,然后将这些组从最高票数到最低票数进行排序。之后,我继续检索候选人的名字,同时保持在积分榜上显示的最大名字数量的计数器,即3。

我尽量使代码尽可能简单,同时保留大部分结构,如果您有任何疑问,请告诉我。

class Program
{
    static Dictionary<string, int> candidates; //Make the variable accesible from any method for simplicity
    static void Main(string[] args)
    {
        //initialize dictionary
        candidates = new Dictionary<string, int>();
        candidates.Add("Ahmed", 0);
        candidates.Add("Boo", 0);
        candidates.Add("Celine", 0);
        candidates.Add("Didi", 0);
        candidates.Add("Elaine", 0);

        //Print candidate names
        for (int i = 0; i < candidates.Count; i++)
        {
            Console.WriteLine("{0} {1}", i, GetCandidate(i));
        }

        //input votes
        Input();

        //output votes if highest vote candidate has any
        if (candidates.Max(c => c.Value) > 0)
        {
            Console.WriteLine("Vote summary");
            Output();

            //to arrange the standings we need to group the candidates to evaluate if they share the same amount of votes
            //additionally I choose to skip the group of candidates who have 0 votes, as there is no point on displaying them

            var grouped_candidates = candidates.GroupBy(c => c.Value).Where(g => g.Key > 0).OrderByDescending(g => g.Key);

            //we can only display 3 names in the standings so we set a counter
            int standing_spots = 3;

            string firstplace = string.Empty, secondplace = string.Empty, thirdplace = string.Empty;

            //retrieve winner(s)
            var first_group = grouped_candidates.ElementAt(0);
            var winner_names = first_group.Select(c => c.Key);
            firstplace = GetStandings("In first place: ", standing_spots, winner_names);

            //retrieve second position(s)
            var second_group = grouped_candidates.ElementAtOrDefault(1);
            if (second_group != null)
            {
                var second_names = second_group.Select(c => c.Key);
                secondplace = GetStandings("In second place: ", standing_spots, second_names);
            }
            //retrieve third position(s)
            var third_group = grouped_candidates.ElementAtOrDefault(2);
            if (third_group != null)
            {
                var third_names = grouped_candidates.ElementAtOrDefault(2).Select(c => c.Key);
                thirdplace = GetStandings("In third place: ", standing_spots, third_names);
            }

            //Print standings
            if (!string.IsNullOrEmpty(thirdplace)) { Console.WriteLine(thirdplace); }
            if (!string.IsNullOrEmpty(secondplace)) { Console.WriteLine(secondplace); }
            Console.WriteLine(firstplace);
        }
        else
        {
            Console.WriteLine("No votes were made!");
        }
        Console.ReadLine();
    }
    static string GetStandings(string standing_txt, int standing_spots, IEnumerable<string> names)
    {
        if (standing_spots > 0)
        {
            if (names.Count() >= standing_spots)
            {
                standing_txt += string.Join("+", names.Take(standing_spots));
                standing_spots = 0;
            }
            else
            {
                standing_txt += string.Join("+", names);
                standing_spots -= names.Count();
            }
        }
        return standing_txt;
    }
    static string GetCandidate(int index)
    {
        return candidates.ElementAt(index).Key;
    }
    static void Input()
    {
        int cand_num;
        do
        {
            cand_num = EnterInt("Enter number of candidate you wish to vote for (0 to 4) or -1 to quit:");

            if (cand_num >= 0 && cand_num <= 4)
            {
                candidates[GetCandidate(cand_num)]++; //increment candidate vote value
            }
            else if (cand_num != -1)
            {
                Console.WriteLine("Invalid vote");
            }

        } while (cand_num != -1);
    }
    public static void Output()
    {
        foreach (var candidate in candidates)
        {
            Console.WriteLine("{0} {1}", candidate.Key, candidate.Value);
        }
    }
    static int EnterInt(string prompt)
    {
        Console.Write(prompt);
        int num;
        while (!int.TryParse(Console.ReadLine(), out num))
        {
            Console.Write("Error! Please enter an integer number:");
        }
        return num;
    }
}