我正在建立一个我已经创建的项目。这是我第一次尝试使用词典/列表。这是一个非常广泛的问题,因为我的书根本没有涉及使用词典,而且我无法在线查找带有用户输入的词典示例。我使用多维数组制作了一个程序,要求用户提供一些学生和一些考试,然后用户输入每个考试的分数,并根据考试分数输出每个学生的平均成绩。我现在想要实现同样的事情,只使用字典和列表而不是数组。我甚至不知道从哪里开始。任何人都可以解释这是如何工作的?这是我已经创建的代码,虽然它可能根本没有帮助:
class MainClass
{
public static void Main(string[] args)
{
int TotalStudents = 0;
int TotalGrades = 0;
Console.WriteLine("Enter the number of students: ");
TotalStudents = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the number of exams: ");
TotalGrades = Convert.ToInt32(Console.ReadLine());
int[,] scoresArray = new int[TotalStudents, TotalGrades];
for (int r = 0; r < TotalStudents; r++)
for (int c = 0; c < TotalGrades; c++)
{
Console.Write("Please enter exam score {0} for student {1}: ", c + 1, r + 1);
scoresArray[r, c] = Convert.ToInt32(Console.ReadLine());
}
for (int r = 0; r < scoresArray.GetLength(0); r++)
{
int studentSum = 0;
int testCount = 0;
for (int c = 0; c < scoresArray.GetLength(1); c++)
{
studentSum += scoresArray[r, c];
testCount++;
}
string gradeLetter = "";
double average = studentSum / testCount;
Console.WriteLine("\nStudent " + (r + 1).ToString() + " Average Score: " + average.ToString());
if (average >= 90)
{
gradeLetter = "A";
}
else if (average >= 80 && average < 90)
{
gradeLetter = "B";
}
else if (average >= 70 && average < 80)
{
gradeLetter = "C";
}
else if (average >= 60 && average < 70)
{
gradeLetter = "D";
}
else
{
gradeLetter = "F";
}
Console.WriteLine("Student " + (r + 1).ToString() + " will recieve a(n) " + gradeLetter + " in the class.\n");
}
Console.Write("\nPress the [ENTER] key to exit.");
Console.ReadLine();
}
}
答案 0 :(得分:1)
字典是一个很棒的工具!我试图使用你原来的逻辑,但有时,我不得不采取另一种方式。此外,我一直迷失在&#34; c&#34;和&#34; r&#34;索引变量。我更喜欢索引的名字。希望这会有所帮助。
//Let's create a gradeTranslator dictionary.
// As the grades follow the simple divisions along averages divisible by 10,
// we can just use the first digit of the average to determine the grade.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
bool useSampleData = true;
Dictionary<string, List<double>> gradeBook = new Dictionary<string, List<double>>();
Dictionary<int, string> gradeTranslator = new Dictionary<int, string>();
for (int i = 0; i < 6; i++) {
gradeTranslator.Add(i, "F");
}
gradeTranslator.Add(6, "D");
gradeTranslator.Add(7, "C");
gradeTranslator.Add(8, "B");
gradeTranslator.Add(9, "A");
gradeTranslator.Add(10, "A");
int TotalStudents, TotalGrades;
// For testing purposes, it is a lot easier to start with some
// sample data. So, I created a query to see if the user wants
// to use sample data or to provide her own input.
Console.WriteLine("Do you want to input the data (I) or allow me to use sample data (S)?");
var inputMethod = Console.ReadLine();
if(inputMethod.ToUpper().IndexOf("I") >=0) {
useSampleData = false;
}
// User Sample Data
if (useSampleData) { // test without using the console input
gradeBook.Add("Bob", new List<double>() { 67.8, 26.3, 33.2, 33.1, 67.2 });
gradeBook.Add("Dick", new List<double>() { 88.2, 45.2, 100.0, 89.2, 91.5 });
gradeBook.Add("Jane", new List<double>() { 99.2, 99.5, 93.9, 98.2, 15.0 });
gradeBook.Add("Samantha", new List<double>() { 62, 89.5, 93.9, 98.2, 95.0 });
gradeBook.Add("Estefania", new List<double>() { 95.2, 92.5, 92.9, 98.2, 89 });
TotalStudents = gradeBook.Count();
TotalGrades = gradeBook["Bob"].Count();
TotalStudents = 5;
// user will provide their own data.
} else {
Console.WriteLine("Enter the number of students: ");
TotalStudents = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the number of exams: ");
TotalGrades = Convert.ToInt32(Console.ReadLine());
for (int studentId = 0; studentId < TotalStudents; studentId++) {
Console.Write("Please enter name of student {0}: ", studentId);
var name = Console.ReadLine();
gradeBook.Add(name, new List<double>());
for (int testId = 0; testId < TotalGrades; testId++) {
Console.Write("Please enter exam score {0} for " +
"student {1}: ", testId + 1, name);
gradeBook[name].
Add(Convert.ToDouble(Console.ReadLine()));
}
}
}
// Here we will divide the grade by 10 as an integer division to
// get just the first digit of the average and then translate
// to a letter grade.
foreach (var student in gradeBook) {
Console.WriteLine("Student " + student.Key +
" scored an average of " + student.Value.Average() + ". " +
student.Key + " will recieve a(n) " +
gradeTranslator[(int)(student.Value.Average() / 10)] +
" in the class.\n");
}
Console.Write("\nPress the [ENTER] key to exit.");
Console.ReadLine();
}
}
}
答案 1 :(得分:0)
建立学生班级以保存信息。
public class Student
{
public string ID
public List<double> TestScores {get;set;}
// in this case average only has a getter which calculates the average when needed.
public double Average
{
get
{
if(TestScores != null && TestScores.Count >0)
{
double ave = 0;
foreach(var x in TestScores)//basic average formula.
ave += x;
// using linq this could be reduced to "return TestScores.Average()"
return ave/TestScores.Count;
}
return 0; // can't divide by zero.
}
}
public Student(string id)
{
ID = id;
TestScores = new List<double>();
}
}
现在您的词典集合可以保留信息。为了帮助您入门,有几种方法可以访问数据。绝对不是全包。
向字典中添加元素:
Dictionary<string,Student> dict = new Dictionary<string,Student>();
Student stud = new Student("Jerry");
dict.Add(stud.ID,stud);
提取信息:
string aveScore = dict["Jerry"].Average.ToString("#.00");
Console.Write(aveScore);
循环通过字典:
foreach(var s in dict.Keys)
{
dict[s].TestScores.Add(50);
}
答案 2 :(得分:0)
由于这是家庭作业,或者您正在尝试学习如何使用词典,而不是发布代码,我只会指出正确的方向。
C#中的Dictionary
是键值对的集合。 Key
必须是唯一的,Value
不一定是Dictionary<int, int> dict = new Dictionary<int, int>();
。因此,如果您按如下方式定义字典:
Key
这意味着您已创建了一组对,其中int
的类型为Value
,int
的类型为index = 0
。因此,如果您向字典添加几个项目,它的内容将如下所示:
在Key=1
,您有一个包含Value=100
和index = 1
的项目。
在Key=2
,您有一个包含Value=200
和Value
的项目。
但是,字典的Collection
不一定必须是单个值。它也可以是Value
(或类对象,甚至是另一个字典)。
由于您的要求是每个学生都有一个分数列表,并且字典Collection
允许Dictionary<string, List<int>>
,因此使用字典看起来确实是一个好主意。但是我们应该使用什么样的字典?
嗯,有很多可供选择。
一种方法是使用string
。表示学生姓名(或ID)的List<int>
和表示考试成绩的Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
。所以;
dict.Add("Arthur Dent", new List<int>() { 75, 54, 26 });
dict.Add("Zaphod Beeblebrox", new List<int>() { 12, 13, 7 });
dict.Add("Ford Prefect", new List<int>() { 99, 89, 69 });
现在,您可以使用每个学生的分数填充此词典。例如:
Value
在您的情况下,您可以从用户那里获得每个学生姓名和分数的输入。
但是,就像我说的那样,你也可以使用类对象作为字典Student
,事实上,这是一个更好的方法来解决你的问题。 Felix的答案显示了如何做到这一点,所以我不会详细介绍。但是你基本上想要创建一个字典如下,假设你的类是Dictionary<string, Student> dict = new Dictionary<string, Student>();
。
Student
然后根据用户输入创建Student
的实例,并将它们添加到字典中。使用Average()
类的另一个好处是,您可以在一个地方获得与一个学生相关的所有信息,并且还有其他帮助方法,例如Felix示例中的def plot(log_name,num):
numbers = [ random.randint(1,20) for _ in range(10) ]
fig = plt.figure() ## crashes here, with no error
ax = fig.add_subplot(1,1,1)
ax.plot(numbers ,numbers ,label="test1")
ax.plot(numbers , numbers , label="test2")
ax.set_xlabel('Test1')
ax.set_ylabel('Test2')
ax.legend()
fig.savefig("figures/"+str(num)+".png")
plt.close(fig)
if __name__ == '__main__':
freeze_support()
## Single process works. A figure is generated
#plot("1",1)
## Multiprocesses doesnt work. No figures will be generated
p1 = Process(target=plot,args=("1",1))
p1.start()
p2 = Process(target=plot, args=("2", 2))
p2.start()
p1.join()
p2.join()
方法,因此您的代码将更清洁,更简单。