Finding Largest Value and Index position

First, I would like to thank Chervil and Yay295 for helping me get this far with a program that has otherwise made me feel defeated at ever trying to become a programmer. I have referenced the templates for finding the largest or highest value of an array; however when working with vector objects I am stuck... again. How might one go about comparing two objects member values (e.g. rivals[x].score)? My goal and final piece of this program is to have the winner or the rival object with the highest score to be assigned to a variable so that I can output it (e.g. rivals[variable].name<<" has won the competition with the score of "<<rivals[variable].score;). I have tried max_element and cannot get it to work. I could write an entirely too long if statement, though that leaves me feeling like I have not learned anything more. Please, if anyone could give me an idea of the algorithm or logic needed to complete this, I would be most grateful.
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
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

struct file_cab
{
    string name;
    double num, numArr[9];
	double score;
};

int main ( )
{
    string file = "scores.txt";
    ifstream read (file);
    int numNum, x, y;
	vector<file_cab>::iterator z;
	read >> numNum;    
    cout << "Number of Contestants: " << numNum << '\n';

	vector<file_cab> rivals (numNum);  
	
	for (x=0; x<numNum;++x) 
    {
		
        read >> rivals[x].name >> rivals[x].num;
		cout << '\n' << rivals[x].name << ' ' << rivals[x].num << ' ';
		
		double scoreB=0;

        for (y=0;y<9;++y )
        {
            read >> rivals[x].numArr[y];
			scoreB += rivals[x].numArr[y];
        }
		double min=rivals[x].numArr[0]; 
		double max=rivals[x].numArr[0];
		
		for (int i=0; i<9; ++i)
		{
			if(rivals[x].numArr[i]<min)
				min=rivals[x].numArr[i];
			if(rivals[x].numArr[i]>max)
				max=rivals[x].numArr[i];
		}
		    scoreB=scoreB-min; 
			scoreB=scoreB-max;
			rivals[x].score=scoreB;
			rivals[x].score=rivals[x].score * rivals[x].num;
			sort (rivals[x].numArr, rivals[x].numArr + 9);

        for (y=0; y<9; ++y ) cout << rivals[x].numArr[y] << ' ';
			cout<<"\nScore for "<<rivals[x].name<<": "<<rivals[x].score<<'\n'<<min<<" "<<max<<" ";
	}
    cout << '\n';
	system("pause");
	return 0;
}


the text file below is what I am using with this program: "scores.txt"

7
Anne 2.0 8.5 8.5 9.0 9.0 9.0 9.5 8.5 8.0 9.5
Sarah 1.6 7.5 8.5 8.0 8.0 7.0 9.0 8.5 8.5 8.0
Deborah 2.3 9.0 9.0 9.5 10.0 10.0 9.5 9.5 9.5 9.5
Kathryn 2.4 9.0 9.0 9.0 9.5 9.5 9.5 9.0 8.0 8.5
Martha 2.7 9.0 9.0 9.5 9.5 9.0 8.5 8.5 8.5 9.5
Elizabeth 2.9 8.0 8.0 7.5 8.5 8.5 8.0 8.0 7.5 8.5
Tina 2.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5 8.5
Last edited on
Keep a global maxScore variable and pointer (ptrfilecab) to file_cab object. Whenever you finish with each person, you simply compare their score to maxScore. If it is greater, you set maxScore to that person's score and you set the pointer to the address of the object.

ex.
53
54
55
56
if (rivals[x].score > maxScore) {
    maxScore = rivals[x].score;
    ptrfilecab = &rivals[x];
}


A note about this method is that you should be careful when using it with an unitialized vector object. i.e. if you declare the vector without specifying the number of elements (unlike what you did on line 24) and place objects in the vector by calling the std::vector<file_cab>::push_back method, you might receive a segmentation fault when you try to access the object referred to by the pointer. This is because a vector is internally represented by a normal C-array and when you have not declared the size during construction, the vector will have to often resize itself; and the memory it used to occupy will no longer be available.

To prevent this from happening, either use a static array - std::array (c++11) or C style array, std::deque, or stick to initializing the vector with a size before placing objects in it.
Last edited on
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
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
double maxScore=0.0;

struct file_cab
{
    string name;
    double num, numArr[9];
	double score;
};
file_cab *ptrfilecab=new(file_cab);
int main ( )
{
    string file = "scores.txt";
    ifstream read (file);
    int numNum,x,y;

	read >> numNum;    
    cout << "Number of Contestants: " << numNum << '\n';

	vector<file_cab> rivals (numNum); 
	
	for (x=0; x<numNum;++x) 
    {
		
        read >> rivals[x].name >> rivals[x].num;
		cout << '\n' << rivals[x].name << ' ' << rivals[x].num << ' ';
		
		double scoreB=0;

        for (y=0;y<9;++y )
        {
            read >> rivals[x].numArr[y];
			scoreB += rivals[x].numArr[y];
        }
		double min=rivals[x].numArr[0]; 
		double max=rivals[x].numArr[0];
		
		for (int i=0; i<9; ++i)
		{
			if(rivals[x].numArr[i]<min)
				min=rivals[x].numArr[i];
			if(rivals[x].numArr[i]>max)
				max=rivals[x].numArr[i];
		}
		    scoreB=scoreB-min; 
			scoreB=scoreB-max;
			rivals[x].score=scoreB;
			rivals[x].score=rivals[x].score * rivals[x].num;
			sort (rivals[x].numArr, rivals[x].numArr + 9);
			if (rivals[x].score > maxScore) 
			{
			maxScore = rivals[x].score;
			ptrfilecab = &rivals[x];
			}
        for (y=0; y<9; ++y ) cout << rivals[x].numArr[y] << ' ';
			cout<<"\nScore for "<<rivals[x].name<<": "<<rivals[x].score<<'\n';

	
	}
	cout<<'\n';
	cout<<'\n'<<"The winner of the competition is: "<<ptrfilecab->name<<" with a score of "<<maxScore<<endl;
    cout << '\n';
	system("pause");
	return 0;
}
Last edited on
Your question has already been solved by what you did on line 59. There is no need to store the index as you already have a pointer to the object that is the winner. Simply do:

66
67
cout << "The winner of the competition is: " << ptrfilecab->name << '\n'
     << "With a score of: " << ptrfilecab->score << endl;
Last edited on
Another option would be to store the index of the file_cab object you want to reference instead of a pointer. Since you are using a vector, the time to grab the object should be constant and you don't need to worry about the address changing if the vector resizes itself as smac89 suggested. If you were using a list data structure, the pointer would be a more efficient, but for a vector there wouldn't be much gain.

Storing the index in a variable (such as, "variable") would then allow you to do the rivals[variable].name that you wanted to do in the first place.
Smac89 thank you. I am always confused as to when to use this (->). I need to read a lot more and cram these other concepts, still. Usually in my programs I would use :: or . for functions and methods on an object or object array. Is -> a function of pointers only, or is -> a pointer to a member of an object?
-> is a way to dereference a pointer.

If you have a pointer p, (*p).member is equivalent to p->member.
Last edited on
To everyone who has helped me with this and replied, thank you. Cire, thank you for the clarification on (->) pointers to a member of an object. The pointer to an object should have been an obvious solution for me Smac89. There is a vector of objects and how else was I going to reference the values of each one?Thank you again for pointing me in the right direction!
Last edited on
Topic archived. No new replies allowed.