need to sort by one column
I have a text file I am reading in that is formatted like so:
Nelson,Bob 80 90 56 90 <-- the whole list has 20 records
where the first part is the name, then testscore1,2,3 and finaltest
I am supposed to sort this list by the final test grade, I can do this ok using a bubble sort, but how can i keep track of which record the finaltest score belongs to?
Here is the code I have currently (I know its messy, I'm in an intro to c++ class)
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
void sortbyFinal(float final[],int);
int main()
{
float test1[20],test2[20],test3[20],test_final[20];
// float average[20];
char student[20][19];
int i = 0;
ifstream inputFile;
ofstream outputFile;
inputFile.open("data2.dat");
outputFile.open("grade2.out");
outputFile << "CS256.002\t\t\tGrade Report\t\t\tSpring 2004\n\n";
outputFile << "Student\tTest1\tTest2\tTest3\tFinal Test";
outputFile << "\t Average\tLetter Grade\n";
outputFile << fixed << setprecision(0);
cout << "Getting Data from file...";
for(i = 0; i < 20; i++)
{
inputFile >> student[i] >> test1[i] >> test2[i] >> test3[i] >> test_final[i];
}
sortbyFinal(test_final,20); // function to sort by final
cout << endl;
outputFile << "\n";
outputFile.close();
}
void sortbyFinal(float final[], int elems)
{
bool swap;
float temp;
do
{
swap = false;
for (int count=0;count<(elems - 1);count++)
{
if(final[count] > final[count+1])
{
temp = final[count];
final[count] = final[count+1];
final[count+1] = temp;
swap = true;
}
}
} while(swap);
cout << endl;
}
I just need some tips on how to go about coding this in a reasonable manner.
Thanks
Dave
# 1 Re: need to sort by one column
Maybe create a student object (class derived from CObject), with members for the student's name and grades.
Create an ObjectArray of student objects (based on file contents) and sort that array based on each students final grade except now you can swap the poitions of each student object rather than just the final grade, thus all grades will stay with the appropriate student, etc.
RussG1 at 2007-11-11 1:21:01 >

# 2 Re: need to sort by one column
you can use struct which would look better (not messy ).
struct STUDENT
{
char name[20];
float test1;
float test2;
float test3;
float final_test;
}student[20];
...
int main()
{
int i = 0;
ifstream inputFile;
ofstream outputFile;
inputFile.open("data2.dat");
outputFile.open("grade2.out");
outputFile << "CS256.002\t\t\tGrade Report\t\t\tSpring 2004\n\n";
outputFile << "Student\tTest1\tTest2\tTest3\tFinal Test";
outputFile << "\t Average\tLetter Grade\n";
outputFile << fixed << setprecision(0);
cout << "Getting Data from file...";
for(i = 0; i < 20; i++)
{
inputFile >> student[i].name >> student[i].test1>> student[i].test2 >> student[i].test3 >> student[i].test_final;
}
sortbyFinal(); // function to sort by final
cout << endl;
outputFile << "\n";
outputFile.close();
}
void sortbyFinal()
{
bool swap;
float temp;
do
{
swap = false;
for (int count=0;count<20;count++)
{
if(student[count].final_test > student[count+1].final_test)
{
//this swap the final test
temp = student[count].final_test;
student[count].final_test = student[count+1].final_test;
student[count+1].final_test = temp;
//also need to swap other data
temp = student[count].test1;
student[count].test1 = student[count+1].test1;
student[count+1].test1 = temp;
...
...
...
//
// its better if the swapping done in another function
// and make sure all the data name,test1,test2,test3 and
// final_test is swapped
swap = true;
}
}
} while(swap);
cout << endl;
# 3 Re: need to sort by one column
this was in response to russ's comment
the problem with that is that we haven't covered classes yet, i think i'm expected to code the program with the material we've covered so far... so what I'm trying to say is I have no idea how to do what you just suggested :D
-Dave
# 4 Re: need to sort by one column
Ok, then you should probably stay away from that for now, but appraoch would be similair.
Create an array of students, representing each student in whatever method you are familair with (struct, vector, array, etc), and sort using same method, but swap the position of the full student object rather than the final grades, so that the grades stay with the student.
I am not sure what the assignment is, or what the assignment is designed to teach, but the idea behind my suggestion, is to somehow represent the student as an object (and then create some sort of array of students, again using what ever method you are familair with) so you can sort the students as a whole object rather than having to swap all the grades and students names individually, etc
RussG1 at 2007-11-11 1:24:05 >

# 5 Re: need to sort by one column
ok, the numbers all match up now, but I'm having problems making the char array swap properly.
this is what i have:
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
struct STUDENT
{
char name[20];
float test1;
float test2;
float test3;
float test_final;
}student[20];
void sortbyFinal();
int main()
{
int i = 0;
ifstream inputFile;
ofstream outputFile;
inputFile.open("data2.dat");
outputFile.open("grade2.out");
outputFile << "CS256.002\t\t\tGrade Report\t\t\tSpring 2004\n\n";
outputFile << "Student\tTest1\tTest2\tTest3\tFinal Test";
outputFile << "\t Average\tLetter Grade\n";
outputFile << fixed << setprecision(0);
cout << "Getting Data from file...";
for(i = 0; i < 20; i++)
{
inputFile >> student[i].name >> student[i].test1>> student[i].test2;
inputFile >> student[i].test3 >> student[i].test_final;
}
cout << "\nPrior to sorting we have:\n";
for(i = 0; i < 20; i++)
{
cout << student[i].name << " " << student[i].test1 << " " << student[i].test2;
cout << " " << student[i].test3 << " " << student[i].test_final << endl;
}
sortbyFinal(); // function to sort by final
cout << "\nAfter sorting we have:\n";
for(i = 0; i < 20; i++)
{
cout << student[i].name << " " << student[i].test1 << " " << student[i].test2;
cout << " " << student[i].test3 << " " << student[i].test_final << endl;
}
cout << endl;
outputFile << "\n";
outputFile.close();
}
void sortbyFinal()
{
bool swap;
float temp;
do
{
swap = false;
for (int count=0;count<20;count++)
{
if(student[count].test_final > student[count+1].test_final)
{
//this swap the final test
temp = student[count].test_final;
student[count].test_final = student[count+1].test_final;
student[count+1].test_final = temp;
//also need to swap other data
float j;
char tempname[20];
j = temp;
tempname[j] = student[count].name;
student[count].name = student[count+1].name;
student[count+1].name = tempname[j];
/*
temp = student[count].name;
student[count].name = student[count+1].name;
student[count+1].name = temp;
*/
temp = student[count].test1; //correct example?
student[count].test1 = student[count+1].test1;
student[count+1].test1 = temp;
temp = student[count].test2;
student[count].test2 = student[count+1].test2;
student[count+1].test2 = temp;
temp = student[count].test3;
student[count].test3 = student[count+1].test3;
student[count+1].test3 = temp;
//
// its better if the swapping done in another function
// and make sure all the data name,test1,test2,test3 and
// final_test is swapped
swap = true;
}
}
} while(swap);
}
I'm not sure how to make the swap with the char arrays work, any ideas?
-Dave
# 6 Re: need to sort by one column
you can do a for loop to swap each char array
for(int i=0;i<20;i++)
{
tempname[i] = student[count].name[i];
student[count].name[i] = student[count+1].name[i];
student[count+1].name[i] = tempname[i];
}
or maybe you can use the strcpy or CString...
# 7 Re: need to sort by one column
I ended up using strcpy and it did the trick...
whew! I spent 15hrs plus on this... i don't think computer programming is for me :(
thanks for your help max and russ
-Dave
# 8 Re: need to sort by one column
I still think using an array of students would be a better approach as you would not need to swap all of the data individually.
i.e.
struct STUDENT
{
char name[20];
float test1;
float test2;
float test3;
float test_final;
};
int _tmain(int argc, _TCHAR* argv[])
{
STUDENT studentArray[20]; // an array of 20 students
// fill array with values, you would do this from your file
for (int i = 0; i < 20; i++)
{
strcpy(studentArray[i].name, "Student");
char *c = new char[3];
sprintf(c, "%d", i);
strcat(studentArray[i].name, c);
delete [] c;
studentArray[i].test1 = i;
studentArray[i].test2 = i;
studentArray[i].test3 = i;
studentArray[i].test_final = i;
}
// sort
bool swap;
do
{
swap = false;
for (int i = 0; i < 19; i++)
{
// sort students from highest grade to lowest
if (studentArray[i].test_final < studentArray[i+1].test_final)
{
STUDENT tempStudent;
tempStudent = studentArray[i];
studentArray[i] = studentArray[i+1];
studentArray[i+1] = tempStudent;
swap = true;
}
}
} while(swap);
return 0;
}
RussG1 at 2007-11-11 1:28:13 >

# 9 Re: need to sort by one column
Also, note that is used i < 19 in the sort rather than i < 20, otherwise when i = 19, i+1 is invalid, and your last item sorted will be corrupted.
RussG1 at 2007-11-11 1:29:13 >

# 10 Re: need to sort by one column
// sort
bool swap;
do
{
swap = false;
for (int i = 0; i < 19; i++)
{
// sort students from highest grade to lowest
if (studentArray[i].test_final < studentArray[i+1].test_final)
{
STUDENT tempStudent;
tempStudent = studentArray[i];
studentArray[i] = studentArray[i+1];
studentArray[i+1] = tempStudent;
swap = true;
}
}
} while(swap);
yes, russ solution seems better, reduces the line of codes and the possiblities of an error to occur.
I always program to get what i need first and then i will try to optimize it, well I still do have a lot to learn.