【问题标题】:Adding integer values from multiple lists from a Dictionary从字典的多个列表中添加整数值
【发布时间】:2023-03-27 18:10:02
【问题描述】:

我正在为我的计算机编程课程尝试用 c# 编写一个项目,但我被部分编程困扰。

我想要做的是将多个列表中存储的整数相加,将其放入一个新列表中,然后输出平均值(列表存储在字典中)。例如,如果我有:

List<int> list1 = new List<int>():  
List<int> list2 = new List<int>():

list1.Add(2);  
list1.Add(3);

list2.Add(1);  
list2.Add(7);

我想要一个新列表,其中包含特定位置处的 int 值的总和,因此在新列表中的位置 0 处,值将是 3,而在位置 1 处,它将是 10。

或者在我的代码的相同主题中,如果 Susan 在她的第一次测试中获得 89 分,在第二次测试中获得 50 分,而 Johnny 在第一次测试中获得 100 分,在第二次测试中获得 89 分,那么测试 1 和 2 的班级平均分是多少? (Susan 和 Johnny 是关键,他们的每个测试都是他们自己列表中的元素)

我不知道这是否会使事情复杂化,但我将每个列表存储在字典中,并以字符串作为键(因为它更容易组织)。这是我的课程代码:

List <int> testInfo;
Dictionary<string, List<int>> dict;
string name;
int testGrade;
int count = 0;
int count2 = 0;
int nameCount = 0;
int gradeCount = 0;

public StudentInfo() 
{

   dict = new Dictionary<string, List <int>>();
}

public void LoadGrades(string name, int testGrade) //adds the inputted values into a list
{
        this.name = name;
        this.testGrade = testGrade;
        testInfo = new List<int>();    

    if (dict.TryGetValue(name, out testInfo))
    {

        testInfo.Add(testGrade);
    }

    else
    {
        testInfo = new List<int>();  //creates a new list if a new key is entered
        testInfo.Add(testGrade);
        dict[name] = testInfo;
    }


}


public void DisplayGrades() //Displays the data entered so far
{
    Console.WriteLine("\nThis is the data you have entered so far.");
    Console.WriteLine("\n{0,-5} {1,20}", "Name", "Grade");
    Console.WriteLine("------------------------------");

    foreach (KeyValuePair<string, List<int>> pair in dict)
    {               
        foreach (int i in pair.Value)
        {
            Console.WriteLine("{0,-5} {1,20}%", pair.Key, i.ToString());
        }

    }
}

public void StuAvg() //Displays the average of each list for its specific key
{
    double average;
    Console.WriteLine("\nThese are the students averages.");

    Console.WriteLine("\n{0,-5} {1,20}", "Name", "Average");
    Console.WriteLine("------------------------------");

    foreach (KeyValuePair<string, List<int>> pair in dict)
    {
        average = Math.Round(pair.Value.Average(), 2);
        Console.WriteLine("{0,-5} {1,20}%", pair.Key, average.ToString());

    }



}

public void TestAvg() //Displays the average for each individual test
{
    List <int> testAvg = new List<int>();
    Console.WriteLine("\nThese are the averages for each test.");

    Console.WriteLine("\n{0,-5} {1,20}", "Test", "Average");
    Console.WriteLine("------------------------------");

        foreach (List<int> i in dict.Values)
        {

          //Adds values in each list together

        }
    }

这是我的主程序:

StudentInfo s = new StudentInfo();
            string name;
            string anoStudent;
            int grade;
            int numTests;
            int count = 1;
            int count2 = 1;

            do
            {
                Console.Write("\nWhat is student {0}s name?: ", count++);
                name = Console.ReadLine();

                Console.Write("\nHow many tests did they take? (Maximum of 8): ");
                numTests = int.Parse(Console.ReadLine());

                while (numTests > 8 || numTests == 0)
                {
                    Console.WriteLine("\nA student can only take up to 8 tests, and has to take at least one to be registered.");
                    Console.Write("Please enter again: ");
                    numTests = int.Parse(Console.ReadLine());
                }


                for (int x = 0; x < numTests; x++)
                {
                    Console.Write("What was their mark for test {0}: ", count2++);
                    grade = int.Parse(Console.ReadLine());

                    while (grade > 100 || grade < 0)
                    {
                        Console.WriteLine("\nA student can't have more than 100 percent or less than 0 percent on any given test.");
                        Console.Write("Please enter again: ");
                        grade = int.Parse(Console.ReadLine());

                    }

                    s.LoadGrades(name, grade); //load input into function

                }


                Console.Write("\nWould you like to add another student? (Yes or No): ");
                anoStudent = Console.ReadLine();

                numTests = 0; //reset variables
                count2 = 1;

            } while (anoStudent.ToLower() == "yes");

            s.DisplayGrades();
            s.StuAvg();
            s.TestAvg();
            Console.ReadKey(true);

我很抱歉冗长,但任何帮助将不胜感激:)

编辑
我修改了 Nicholas 建议的非 LINQ 方法,该方法将允许它计算多个列表的平均值,确保仅对已添加在一起的列表位置进行平均,从而不影响未更改的位置。为了准确起见,我还将原始整数列表更改为双列表。

我想你们可能想看看完成的代码,所以这是它的功能:)

 public void TestAvg() //Calculate the class average for each test
{
    List<int> counter = new List<int>(); //A list to hold the amount of students that took each test
    List<double> results = new List<double>(); //Create a new list to hold the final test averages
    double testAvg;

    Console.WriteLine("\nThis is the class average for each test.");

    Console.WriteLine("\n{0,-0} {1,20}", "Test", "Average");
    Console.WriteLine("--------------------------------------------------");

        foreach (List<double> l in dict.Values) //For every list in dict.Values
        {

            count2++; //Create a counter 

            for (int x = 0; x < l.Count(); x++ ) //Until x reaches the amount of elemets in l (list)
            {
                double value = l[x];   //Create a variable that will hold the value of l at location x                 

                if (x < results.Count) //if x is less than the amount of elements in results
                {
                    results[x] += value; //the value at x is equal to the value at x plus the variable value
                    counter[x] += 1;               
                }

                else
                {
                    results.Add(value); //Otherwise value is instead just added to the list, instead of being sumemd into the previous locations       
                    counter.Add(1);   
                }
            } 
        }

        for (int i = 0; i < results.Count; i++)
        {
            results[i] = results[i] / counter[i]; //Take the values at x in results and divide it by the amount of students that took each test (find the average)    
        }     

    foreach (double d in results) //For every double value in the list
    {                           
                testAvg = Math.Round(d, 2); //Round it to 2 decimal places
                Console.WriteLine("{0,-0} {1,20}%", count++ + 1, testAvg); //Output results                                                                             
    }          
}

【问题讨论】:

  • 这对于您第一次使用 SO 来说根本不是一个坏问题,但您向我们解释您在什么时候遇到困难是非常重要的。 What I want to do is add integers stored in multiple lists together, put that into a new list, then output the average (with the lists being stored in a dictionary).这部分你做不到?分手吧,你自己想办法吧!
  • 问题到底是什么?我希望你不是在找人来做你的项目。
  • 我不知道如何将多个列表中的整数相加,例如,从每个列表中的位置 0 开始,我想将该特定位置中的所有值相加。 :(

标签: c# list dictionary


【解决方案1】:

如果您已将所有列表添加到字典中,那么您可以这样做:

var query = dict.Values.Select(r => r.Select((number, i) => new { Index = i, Number = number }))
    .SelectMany(r => r)
    .GroupBy(r => r.Index)
    .Select(grp => new
    {
        Index = grp.Key,
        Value = grp.Sum(t => t.Number)

    });

假设你有这样的列表:

List<int> list1 = new List<int>();
List<int> list2 = new List<int>();

list1.Add(2);
list1.Add(3);

list2.Add(1);
list2.Add(7);
Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
dict.Add("1", list1);
dict.Add("2", list2);

然后在执行 LINQ 查询 (first code sn-p) 你可以这样做:

foreach (var item in query)
{
    Console.WriteLine("Index: {0}, Sum: {1}", item.Index, item.Value);
}

你会得到:

Index: 0, Sum: 3
Index: 1, Sum: 10

【讨论】:

  • 哇,谢谢!那比我快,谢谢:) 那是 Linq 不是吗?我还不太熟悉,你给我解释是不是太麻烦了?我想了解我在编码什么^^
  • @ThatOneCanadian,是的,它的 LINQ,它的核心是使用Enumerable.Select 重载,它也将索引作为参数。
【解决方案2】:

这是一种简单的非 LINQ 方法,可以按照您描述的方式对任意数量的列表求和:

static List<int> SumOfLists( params List<int>[] lists )
{
  return SumOfLists( (IEnumerable<List<int>>) lists ) ;
}

static List<int> SumOfLists( IEnumerable<List<int>> lists )
{
  List<int> result = new List<int>() ;

  foreach ( List<int> list in lists )
  {

    for( int j = 0 ; j < list.Count ; ++j )
    {
      int value = list[j] ;

      if ( j < result.Count )
      {
        result[j] += value ;
      }
      else
      {
        result.Add( value ) ;
      }

    } // end for-j

  } // end for-each

  return result ;
}

【讨论】:

  • 非常感谢,我可以更容易理解这个语法了:)
猜你喜欢
  • 2019-12-14
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 2018-03-27
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多