我正在尝试使用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
}
}
答案 0 :(得分:2)
如果您已将所有列表添加到词典中,则可以执行以下操作:
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查询(第一个代码片段)后,你可以这样做:
foreach (var item in query)
{
Console.WriteLine("Index: {0}, Sum: {1}", item.Index, item.Value);
}
你会得到:
Index: 0, Sum: 3
Index: 1, Sum: 10
答案 1 :(得分:1)
这是一个简单的非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 ;
}