Alphabetizing Names

Hello!

I have come across a programming assignment in which I am struggling to complete. The problem states:

"A teacher has asked all her students to line up single file according to their first name. For example, in one class Amy will be at the front of the line and Yolanda will be at the end. Write a program that prompts the user to enter the number of students in the class, then loops to read in that many names. Once all the names have been read in it reports which student would be at the front of the line and which one would be at the end of the line. You may assume that no two students have the same name."

also..

Do not accept a number less than 1 or greater than 25 for the number of students.

Please note that I am not allowed to use arrays because "we have not learned how to use them yet" and I must use a loop to get the input from the user.

This is what I have so far (the easy stuff...)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>

using namespace std;

int main()
{

	int numStudents;
	int count = 0;
	string name, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10, name11, name12, name13, name14, name15, name16, name17, name18, name19, name20, name21, name22, name23, name24, name25;


	//get the number of students
	cout << "Enter the number of students: ";
	cin >> numStudents;


	//check for 1 to 25 students
	if (numStudents < 1 || numStudents > 25)
		cout << "Error: Please enter a number between 1 and 25." << endl;



	system("pause");
	return 0;
Last edited on
Arrays? I wouldn't bother with an array for this. I would use a deque or vector but I am guessing that isn't allowed either. Well, the best way to do this is to do the sorting to the file directly. There are ways to input stuff in the middle of files so what you can do is write up a quick function that determines where in the file it belongs and place it there.

Also here is something you probably were not told in class but will be graded on, you need to pay attention to upper and lower case. They will also be sorted but not the way you want them. When you do your testing, make sure you upper or lower case all the strings first. You can copy them to a separate string so your original data remains untouched. The easiest way after that is to just use the chars and remember that they are also 16 bit integers.

'a' < 'b'
'a' + 2 > 'b'
'a'+1 == 'b'
'B' < 'b'
Your saying I should have the information outsources to a separate file and then read in the information for alphabetizing?

If that is the case I do not believe that is in my range of knowledge. We are working with single .cpp files and all user input goes directly into the program via cin.

I did notice that the letters "A" and "a" are different, however my instructor neglected to mention that.

Seeming as I am a bit confused would It be possible to provide a short example using three names/words?
Sucks that you can't use arrays dude. Would have made life so much simpler
Yes it is horrible. Our instructor is just making it much more complicated this way.

Side Note:

Here is an update on my code (I know it's not much but it's a start)

I have a feeling that the absurd amount of string variables are unnecessary..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{

	int numStudents;
	string name, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10, name11, name12, name13, name14, name15, name16, name17, name18, name19, name20, name21, name22, name23, name24, name25;


	//get the number of students
	cout << "Enter the number of students: ";
	cin >> numStudents;


	//check for 1 to 25 students
	if (numStudents < 1 || numStudents > 25)
		cout << "Error: Please enter a number between 1 and 25." << endl;

	//get student names
	for (int count = 1; count <= numStudents; ++count)
	{
		cout << "Enter the students name: " << endl;
		cin >> name;
	}

	system("pause");
	return 0;

}
I have a feeling that the absurd amount of string variables are unnecessary..

Yes, which arrays are perfect for dealing with. With an array, you can declare 25 string variables at once using the statement
string name[25];

Just a quick note. You may want to change
1
2
if (numStudents < 1 || numStudents > 25)
	cout << "Error: Please enter a number between 1 and 25." << endl;

to..
1
2
3
4
5
while(numStudents < 1 || numStudents > 25)
{
      cout << "Error: Please enter a number between 1 and 25." << endl;
      cin >> numOfStudents;
}


Why? Because as you have it now, you're not giving the user the chance to reenter the number of students. Also, you need the while loop because your user can enter as a wrong value for numOfStudents as many times as they want, theoretically...

I can't think of any way to do this program without the use of arrays, vectors, or such however:(
Thank you for the tip on the while statement. I was just trying to set that part up.

I appreciate any input I can get considering I am completely lost on how to go about writing this. I have heard something about "bubble looping" (I think that is what it is called) or something like that which may be within my limitations.

Something about using the getline. to retrieve strings... I'm not really sure.
Maese909 wrote:
I can't think of any way to do this program without the use of arrays, vectors, or such however:(


I'm also having a hard time visualizing any way to do this without use of an array AND loop to gather input.

This is ironic because a string is essentially an array of characters, if i'm not mistaken.

In order to have a loop to get the input you will need some sort of array/vector/etc. so that the compiler will understand to move onto the next entry, otherwise I do not believe there is any way to tell it to go to var2,var3, etc. through a loop. Therefore, you have two options.

Either declare it as an array using string name[25], then perform a loop that would look something like:

1
2
3
4
5
6
for (int i=0; i<=numStudents; i++)
{
    cout<<"Enter name of "<<i<<"th student: ";
    cin>>name[i];
    count++;
}


Then call the name of the first student later on by name[0] and last student: name[count]

Alternatively, if you cannot use arrays then you will also not be able to use a loop. Namely, you will come up with a veeeeeery long code involving tons of if-statements depending on the input of the user, etc. etc.

I'm pretty sure you're allowed to use string name[25]. Otherwise, imo your teacher is an idiot and everyone is going to end up with giant inneficient code, undoubtedly with tons of errors.
Last edited on
I am going to take your advice and use arrays. Once I sort through the code and implement it into my program I will post my progress. If it works 100% I will consider this topic resolved.

Thank you for the help.
There are some mistakes with the code that I suggested to you as I didn't get a chance to apply any of the suggestions and compile the code. I apologize, here is the revised code with the suggestions that I gave you, I believe it should work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<string>

using namespace std;

int main()
{
	int numStudents;
	int count=0;

	//get the number of students
	cout << "Enter the number of students: ";
	cin >> numStudents;

while(numStudents < 1 || numStudents > 25)
{
      cout << "Error: Please enter a number between 1 and 25." << endl;
      cin >> numStudents;
}

string name[numStudents];

	//get student names
	for (int i=0; i<numStudents; i++)
{
    cout<<"Enter name of student number "<<i+1<<": ";
    cin>>name[i];
    count++;
}

	return 0;

}


I also took the liberty of removing system("PAUSE"); because it is evil.

Do you understand the concept of the array and what is happening inside the loop?

EDIT: Side note that might help you avoid a lot of confusion while trying to solve the next bit: The first entry in an array starts from 0, not 1. Namely, array[0] calls the first entry in the array, array[1] calls the second entry, and so on, so forth.
Last edited on
I know that the array takes the input and gives it a subscript ex. 0, 1, 2... and then uses that subscript to call the function. However I'm unsure as how I would compare these strings alphabetically to each other without massive amounts of excess code.

EDIT: Also my compiler says that string name[numStudents]; must have a constant value.
Last edited on
jsmith1992 wrote:
how I would compare these strings alphabetically to each other without massive amounts of excess code.


By utilizing nested loops like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
#include<string>

using namespace std;

int main()
{
	int numStudents;
	int count=0;

	//get the number of students
	cout << "Enter the number of students: ";
	cin >> numStudents;

while(numStudents < 1 || numStudents > 25)
{
      cout << "Error: Please enter a number between 1 and 25." << endl;
      cin >> numStudents;
}

string name[numStudents];

	//get student names
	for (int i=0; i<numStudents; i++)
{
    cout<<"Enter name of student number "<<i+1<<": ";
    cin>>name[i];
}

//Part 2: Performing alphabetization of names.

string nTemp; //this is just a temporary storage location


/*Here we will make a loop that will not only determine which student is first,
/last, etc. but will actually completely reorganize all entries in the array
alphabetically, which is a much more efficient way of doing it.*/
for (int j=1;j<numStudents;++j)
{
    nTemp = name[j];
    int k;
    
    for (k = j-1; k>=0 && name[k] > nTemp; k--)
    {
        name[k+1] = name[k];    
    }
    name[k+1] = nTemp;
}

cout<<"\nThe first student is: "<<name[0]<<endl;
cout<<"The last student is: "<<name[numStudents-1]<<endl;
}
Okay so I have the general setup completed and for the most part I can tell what the nested loop is doing, the only problem I am having is my compiler says that string name[numStudents]; must have a constant value.
If you want a break down of what the loops are doing, here it is:

First you need to imagine that you are doing it manually. How would you go about doing this? You would start by taking the first entry and keeping it in mind (this is the temp. storage location, or in our case nTemp. Next, you would compare it with the second entry to see if the second entry is greater. If it is the you move on to the 3rd entry, if the 3rd entry is less then in that case you ignore the first entry that you have in your temp. storage and replace it with the 3rd entry, you repeat this process until you have gone through all entries and have the lowest possible entry and then store that as the first entry in the array. The outer loop basically repeats the inner loop until it has replaced all the entries in the array with the sorted entries.

As for the error that you are getting. I do not understand why you are getting an error, it works fine for me. What IDE/compiler are you using?

EDIT: If you want, you can change string name[numStudents]; to string name[25];. It should still work fine, I don't see how this would create any problems. Having it dynamically change is just a more efficient way of doing it, especially if you have a much higher limit on the amount of strings. But for something small like 25, it's not that big of a deal.
Last edited on
I am using Visual Studios 2010. I entered 25 and it worked just fine. I really appreciate all of your help and your explanation cleared things up.
There is a special feature when working with <fstream> when you are outputing to a file that you can actually decide where you want the information oututed to in the file. You don't have to put it in at once or at the end, you can read it in line by line, detemine if it goes before or after this line and continue until you decide the data is going exactly where you want it to go.

It is called Random File Access. It uses

1
2
3
4
5
seekg();
tellg();

seekp();
tellp();


The g's are for reading, the p's are for writing.

This info should help you out, you can write anywhere and read anywhere in a file meaning you add the first name Amber, then you read the file and determine Yolanda goes after Amber. Then you read the file for the name John and determine it goes after Amber but before Yolanda. This is the point of seek and tell and it is the best you can do without arrays, vectors, or deques.
Topic archived. No new replies allowed.