bubble sort of full names using operators

Sep 11, 2019 at 7:41pm
I cannot for the life of me figure out how to make these names sort correctly. Is my problem in my operator class, or am I just messing up the main function sort?

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  #include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

#include "person.h"


#define ARRAY_MAX 20

// function Declaration

int read_file(string fname,person people[], int max);
/**************************************
* main()
***************************************/
void main()
{
	
	person people[ARRAY_MAX]; // class array
	int i, n; // place holders and loops
	person temp; // temp for swapping names
	
	string fname; // hold file name

	// Get file name

	cout << "Enter file name: ";
	cin >> fname;

	// Read from file
	
	n = read_file(fname, people, ARRAY_MAX); 
	
	// loop to sort data
	for (i=0;i<n;i++)
		for(int j=0;j<n;j++)
	{
			if (people[i] > people[j])
			{
				temp = people[i];
				people[i] = people[j];
				people[j] = temp;

			}
			
			
	}
	// Matching output of assignment
	cout << left << setw(15) << "Last";
	cout << right << setw(15) << "First";
	cout << right << setw(15) << "Age" << endl;

	cout << left << setw(15) << "-----------";
	cout << right << setw(15) << "--------";
	cout << right << setw(15) << "---" << endl;
	// Display array
	for (i = 0; i < n; i++)
		people[i].put(cout);
	system("pause");
	
	
	
}

/*********************************
 * read_file()
 *********************************/
int read_file(string fname,person people[], int limit)
{
	int i;
	fstream in;
	
	// Initialize

	i = 0;

	// Open file

	in.open(fname, ios::in);
	if (!in.is_open()) return 0;

	// Loop through file

	while (!in.eof() && i < limit)
	{
		people[i].get(in); // store data into class
		i++;
		
	};

	// Close file

	in.close();

	// Return count
	
	return i;
}


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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

#include "person.h"
/**************************************
* default constructor 
***************************************/
person::person()
{
	

}
/**************************************
* Constructor - all parameters
***************************************/

person::person(string f, string l, int a)
{
	l = last;
	f= first;
	 a = age;
}

/**************************************
* Get
***************************************/

bool person::get(istream &in)
{
	in >> first;
	in >> last;
	in >> age;
	return (in.good());
}

/**************************************
* output
***************************************/

void person::put(ostream &out)
{
	out << fixed << setprecision(2);
	out << left << setw(15) << last;
	out << right << setw(15) << first;
	out << right << setw(15) << age;

	
	out << endl;
	
}
/**************************************
* operator == to
***************************************/
bool person::operator==(const person &a)
{
	
	person x = *this;
	if (a.last == x.last)
	{
		return true;
	}
	else if (a.first == x.first)
	{
		return true;
	}
	else if (a.age == x.age)
	{
		return true;
	}
	else
	return false;
}
/**************************************
* operator > than
***************************************/
bool person::operator>(const person &a)
{
	
	person x = *this;
	if (a.last > x.last)
	{
		return true;
	}
	else if (a.first > x.first)
	{
		return true;
	}
	else if (a.age > x.age)
	{
		return true;
	}
	else
		return false;
}
/**************************************
* operator < than
***************************************/
bool person::operator<(const person &a)
{
	person x = *this;
	if (a.last < x.last)
	{
		return true;
	}
	else if (a.first < x.first)
	{
		return true;
	}
	else if (a.age < x.age)
	{
		return true;
	}
	else
		return false;
}

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

class person
{
public:
person();// constructor empty
person(string, string, int);// constructor with parameters
bool get(istream &in); //input of class
void put(ostream &out); // output of class
bool operator==(const person &a); // compare names
bool operator>(const person &a);
bool operator<(const person &a);
private:
string first, last;// first and last name
int age;// age

};

 

txt file

Ann Christensen 70
Carlos Morales 68
David Bowman 45
Frank Bowman 37
John Bowman 30
Kathleen Gueller 34
Mark Bowman 42
Mark Bowman 13
Richard Bowman 47
Susan Cox 36
Last edited on Sep 11, 2019 at 8:02pm
Sep 11, 2019 at 7:45pm
main should return int, but as for your actual logic, yes your <, > operators logic is wrong, and I would say so is your == operator, both for similar reasons.

Suppose a.last < x.last, but a.first is still > x.first. This will return true. Is that what you want?

When you say two objects are equal, usually that means that ALL of their subcomponents are equal, not just one or two of them.

Edit: See this SO post for an example of popular patterns for comparing based on multiple values
https://stackoverflow.com/a/3574724/8690169
Last edited on Sep 11, 2019 at 7:48pm
Sep 11, 2019 at 8:10pm
Enter file name: people.txt
Last First Age
----------- -------- ---
Bowman David 45
Bowman Frank 37
Bowman John 30
Gueller Kathleen 34
Bowman Mark 13
Bowman Mark 42
Bowman Richard 47
Cox Susan 36
Christensen Ann 70
Morales Carlos 68
Press any key to continue . . .

This is my current output, only gueller is out of place
Sep 11, 2019 at 8:15pm
You haven't read @Ganado's post. The logic in bool person::operator<(const person &a) is wrong.
Sep 11, 2019 at 8:31pm
Furthermore:
1
2
3
4
5
6
for ( i=0; i<n; i++ )
  for( int j=0; j<n; j++ ) {
    if ( people[i] > people[j] ) {
      // swaps them
    }
  }

Lets say n==2.

When i==0 and j==1 you do swap, if p[0] > p[1]
Now we know that p[0] <= p[1]

Then, i==1 and j==0 you do swap, if p[0] < p[1] (as it most likely is)

Therefore, after loops p[0] >= p[1]


What does happen, if:
1
2
3
4
5
6
for ( i=0; i<n; i++ )
  for( int j=i+1; j<n; j++ ) {
    if ( people[i] > people[j] ) {
      // swaps them
    }
  }

Sep 11, 2019 at 8:45pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
bool person::operator>(const person &a)
{
	
	person x = *this;
	if (a.last > x.last)
	{
		return true;
	}
	else if (a.last == x.last)
	{
		if (a.first > x.first)
		{
			return true;
		}
		else if (a.first == x.first)
		{
			if (a.age > x.age)
			{
				return true;
			}
		}
	}
return false;
}

I changed my operator to this and it worked correctly, thank you everyone for helping
Last edited on Sep 11, 2019 at 8:46pm
Topic archived. No new replies allowed.