2012-12-04 116 views
-1

我有一個鋸齒陣列來獲取學生和主題的詳細信息,我使用了2個鋸齒陣列,一個用於學生的詳細信息(名稱和rollno),另一個用於主題的詳細信息(主題和標記),現在我想總結一下特定學生的所有標記,誰能告訴我怎麼去解決這個問題,下面是我的整個代碼。在鋸齒陣列中總結數值

public void GetStudentDetails() 
     { 

      Console.WriteLine("Please enter number of Students"); 
      int STUDENTS = Convert.ToInt32(Console.ReadLine()); 
      Console.WriteLine("Please enter number of Subjects"); 
      int SUBJECTS = Convert.ToInt32(Console.ReadLine()); //0 is reserved for the student name, so the marks starts from the index 1, hence if you set the marks for 3, it will ask for 2 marks 


      string[][] student_details = new string[STUDENTS][]; 
      string[][] subject_details = new string[SUBJECTS][]; 
      string[][] result_details = new string[STUDENTS][]; 

      StringBuilder stud_sub_info = new StringBuilder(); 
      stud_sub_info.Append("Name\tRoll-No\t"); 
      for (int a = 0; a < STUDENTS; a++) 
      { 
       student_details[a] = new string[STUDENTS * 2]; 
       for (int b = 0; b < 2; b++) 
       { 
        Console.WriteLine("Enter Student {0} {1}:", a + 1, (b == 0) ? "Name" : "Roll-No"); 
        student_details[a][b] = Console.ReadLine(); 
       } 
       for (int c = 0; c < SUBJECTS; c++) 
       { 
        subject_details[c] = new string[SUBJECTS * 2]; 
        for (int d = 0; d < 2; d++) 
        { 
         if (d == 0) 
         { 
          Console.WriteLine("Enter Name for Subject {0}", c + 1); 
          subject_details[c][d] = Console.ReadLine(); 
          stud_sub_info.Append(subject_details[c][d] + "\t"); 
         } 
         else 
         { 
          Console.WriteLine("Enter Marks for {0}", subject_details[c][d - 1]); 
          subject_details[c][d] = Console.ReadLine(); 
         } 
        } 
       } 
      } 
      Console.WriteLine(stud_sub_info.ToString()); 
      for (int a = 0; a < STUDENTS; a++) 
      { 
       for (int b = 0; b < 2; b++) 
       { 
        Console.Write(student_details[a][b] + "\t"); 
       } 
       for (int c = 0; c < SUBJECTS; c++) 
       { 
        for (int d = 0; d < 2; d++) 
        { 
         Console.Write(subject_details[c][d] + "\t"); 
        } 
       } 
      } 
     } 

回答

1

我當然不會使用這樣的鋸齒狀數組。它使編碼困難。

例如,在您的代碼中,您正在爲每個學生捕獲主題標記,但是當您清除之前學生的數據時。 subject_details交錯排列的數組沒有學生的索引。隨時隨地覆蓋數據。您需要將該陣列聲明爲string[][][]

這裏是你的代碼,更簡單,將工作:

string[][] student_details = new string[STUDENTS][]; 
string[][][] subject_details = new string[STUDENTS][][]; 
string[][] result_details = new string[STUDENTS][]; 

for (int a = 0; a < STUDENTS; a++) 
{ 
    student_details[a] = new string[STUDENTS * 2]; 
    subject_details[a] = new string[SUBJECTS][]; 
    Console.WriteLine("Enter Student {0} {1}:", a + 1, "Name"); 
    student_details[a][0] = Console.ReadLine(); 
    Console.WriteLine("Enter Student {0} {1}:", a + 1, "Roll-No"); 
    student_details[a][1] = Console.ReadLine(); 
    for (int c = 0; c < SUBJECTS; c++) 
    { 
     subject_details[a][c] = new string[SUBJECTS * 2]; 
     Console.WriteLine("Enter Name for Subject {0}", c + 1); 
     subject_details[a][c][0] = Console.ReadLine(); 
     Console.WriteLine("Enter Marks for {0}", subject_details[a][c][0]); 
     subject_details[a][c][1] = Console.ReadLine(); 
    } 
} 
for (int a = 0; a < STUDENTS; a++) 
{ 
    Console.Write(student_details[a][0] + "\t"); 
    Console.Write(student_details[a][1] + "\t"); 
    for (int c = 0; c < SUBJECTS; c++) 
    { 
     Console.Write(subject_details[a][c][0] + "\t"); 
     Console.Write(subject_details[a][c][1] + "\t"); 
    } 
} 

現在因爲我們忽略了這一事實,每一個學生都必須有相同數量的科目和您允許的非數字進入主題分數,你可以使用下面的LINQ查詢將鋸齒狀的數組變成可行的。

var query = 
    from i in Enumerable.Range(0, STUDENTS) 
    let Name = student_details[i][0] 
    let RollNo = student_details[i][1] 
    let Subjects = (
     from j in Enumerable.Range(0, SUBJECTS) 
     let Subject = subject_details[i][j][0] 
     let Marks = int.Parse(subject_details[i][j][1]) 
     select new { Subject, Marks } 
    ) 
    select new { Name, RollNo, Subjects }; 

這讓我看起來像這樣的結構:

query data structure

現在你可以使用這個查詢來獲取佔總分:

var results = 
    query 
     .Select(x => new 
     { 
      x.Name, 
      TotalMarks = x.Subjects.Sum(y => y.Marks) 
     }); 

現在這個樣子:

total marks

+0

儘管需要稍微修改student_details [STUDENT * 2]和subject_details [SUBJECT * 2],在這兩種情況下(* 2)都不是必需的,因爲它會在數組中創建空白索引,所有其他代碼都會休眠很好,最好的部分是它的整潔,然後我的 – Abbas

2

使用Linq,Collections和創建類而不是參差不齊的數組會更容易。這將允許你將1個學生連接到許多課程,並且在每門課程中都有許多作業。然後LINQ的語句如:

Sum(x => x.StudentGrade) 

下面是什麼,我會在開始時只是爲了得到什麼,我可以用資金做一個想法存根複印件,以及其他信息:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace StudentManagement { 
    public class Student { 

    public static void Main(string[] args) { 
     List<Student> students = new List<Student>(); 

     Console.Write("Enter number of students: "); 
     int numStudents = int.Parse(Console.ReadLine()); 

     for (int i = 0; i < numStudents; i++) { 
     Student s = new Student(); 
     students.Add(s); 
     } 

     Console.Write("Press any key to continue..."); 
     Console.ReadKey(true); 
    } 

    public string FirstName { get; set; } 
    public List<Course> Courses { get; set; } 

    public Student() { 
     this.Courses = new List<Course>(); 

     Console.Write("Enter First Name: "); 
     this.FirstName = Console.ReadLine(); 

     Console.Write("Enter in number of courses: "); 
     int numCourses = int.Parse(Console.ReadLine()); 

     for (int i = 0; i < numCourses; i++) { 
     Course course = new Course(); 
     this.Courses.Add(course); 
     } 

    } 
    } 

    public class Course { 
    public string Title { get; set; } 
    public string Code { get; set; } 
    public string Section { get; set; } 
    public List<Assignment> Assignments { get; set; } 

    public Course() { 
     this.Assignments = new List<Assignment>(); 

     // Set Title, Code, Section 
     Console.Write("Enter nuber of assignments: "); 
     int numAssignments = int.Parse(Console.ReadLine()); 

     for (int i = 0; i < numAssignments; i++) { 
     Assignment assignment = new Assignment(); 
     this.Assignments.Add(assignment); 
     } 

    } 
    } 

    public class Assignment { 
    public string Name { get; set; } 
    public double MaxGrade { get; set; } 
    public double StudentGrade { get; set; } 

    public Assignment() { 
     // Prompt for Name, MaxGrade, StudentGrade 
    } 
    } 
} 
+0

我絕對同意,數組龐大的代碼花了我5分鐘的時間來理解,還有5分鐘來決定我是否有足夠的精力來構建一個有建設性的答案。 +1給你。 –

+0

有趣的是,我的學生們在兩週前的課堂上完成了這項任務,當時我們通過集合和Linq進行所有權鏈接。 –

+0

@Damon:如果你不介意能不能告訴我循環如何繼續接受用戶的輸入,我也認爲你的代碼會優化性能。 – Abbas