Performing a function on each member of a list

I currently have a program which reads in X and Y coordinates from a .txt document, stores those coordinates in an object and then stores those objects in a list.
I need to perform a function on each one of those objects to work out the importance of the point. I know the function I need to use, but I am not sure how to use it on each point of the list.

I had considered making it one of the methods in the constructor class I use to create the objects, but I do not know how to go about this, does anyone have any advice?

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
//This is the header file which contains the constructor
#ifndef HEADER_H
#define HEADER_H

#include <iostream>
#include <cstdlib>
#include <list>
#include <fstream>

using namespace std;

class Vertex
{
protected:
	int X;
	int Y;
	double F;
	
public:
	Vertex(int x_in, int y_in);
	void setF(double F_in);
	void Importance();
	int getX();
	int getY();
	double getF();
};
#endif

//This is the file which contains the constructors functions (importance was where I would put my maths. 
#include "Header.h"

Vertex::Vertex(int x_in, int y_in)
{
	X = x_in;
	Y = y_in;
}

int Vertex::getX()
{
	return X;
}

int Vertex::getY()
{
	return Y;
}

double Vertex::getF()
{
	return F;
}

void Vertex::setF(double F_in)
{
	F = F_in;
}

void Vertex::Importance()
{
	
}

//Main
#include "Header.h"

int main(void)
{
	import();
	
	system("PAUSE");
}

void import()
{
	ifstream Input;
	Input.open("Swallow.txt");
	list<Vertex> Xlist;
	

	while (!Input.eof())
	{
		int x;
		int y;

		Input >> x >> y;

		Vertex v1( x, y);

		Xlist.push_back(v1);

		if (Input.eof()) break;

	}

	Input.close();
	cout << "Import finished" << endl;

// This is the method I want to use on each object, xP, yP are the x and y stored in the object 
//and xL,yL and xR, yR are the x and y coordinates on the points either side of that object in the list. 

double importanceMethod(int xP, int yP, int xL, int yL, int xR, int yR)
{
	int PL = pow((xP + xL),2) + pow((yP + yL),2);
	int PR = pow((xP + xR),2) + pow((yP + yR),2);
	int LR = pow((xL + xR),2) + pow((yL + yR),2);

	int F = sqrt(PL) + sqrt(PR) - sqrt(LR);
	return F;
}



Thank you in advance for any help

Jack Perry
Last edited on
Personally, I would use a vector as it allows access to any element through the syntax of myVector[X];, but if you have your heart set on using a list...
Perhaps use an itterator of some sort (http://www.cplusplus.com/reference/list/list/) to parse through the list.
Unfortunately I have to use a list, because later on I will be removing the object which returns the lowest F value from the list. I will experiment with iterators though thank you.
That's no reason not to use a vector. http://www.cplusplus.com/reference/vector/vector/erase/

I'm not really familiar with lists, but if you use a vector and build it like I showed in your other thread all you would need to do to access the different members would be something like this.
1
2
xP = v1[index].x;
yP = v1[index].y;

I don't really understand where F comes into play since it isn't part of the list/vector to begin with.
closed account (D80DSL3A)
I think line 88 (presently empty) is the best place to calculate F at.
87
88
89
90
91
Vertex v1( x, y);// newest one

//you can calculate F for Xlist.back() here easily

Xlist.push_back(v1);

Can you see how?

Using a list should be fine. More about your file reading method to follow (it' not ideal).

your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (!Input.eof())// doesn't mean much. We haven't read the data yet.
	{
		int x;
		int y;

		Input >> x >> y;// Input could fail here. x,y are left with uncertain values.

		Vertex v1( x, y);

		Xlist.push_back(v1);// one invalid Vertex gets pushed back.

		if (Input.eof()) break;

	}

Better:
1
2
3
4
5
6
7
8
9
10
int x;		
int y;

while ( Input >> x >> y )// failure aborts the while loop
	{		
               // the data in here is certainly valid
		Vertex v1( x, y);
		Xlist.push_back(v1);
	//	if (Input.eof()) break;// no need for this either
	}


Fewest lines?
1
2
int x, y;
while ( Input >> x >> y ) Xlist.push_back( Vertex(x,y) );


EDIT: re. where to calculate F. The above advice proved less than ideal. It leaves the last Vertex with F unassigned, so you have to go through the whole iterater examination again just for that last one.

It was easier to do it after the entire list was filled.
Here's part of my code for this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
list<Vertex>::iterator iter = Xlist.begin();
    while( iter != Xlist.end() )
    {
        int xL=0, yL=0, xR=0, yR=0;

        if( iter != Xlist.begin() )
        {
            list<Vertex>::iterator itPrev = iter;
            --itPrev;
           // assign values to xL and yL using itPrev
        }

       // similarly for xR and yR. WATCH OUT FOR Xlist.end()

       iter->F = importanceMethod(iter->X, iter->Y, xL, yL, xR, yR);
       ++iter;
    }
Last edited on
Thank you very much I see how that would work, but I am confused as to where in the program I would place this, I tried placing it in main, but then Xlist is no longer recognised.
closed account (D80DSL3A)
It goes in the import() function.
I also appear to be wrong about how to assign values to xL, yL etc.

I thought it would just be

1
2
xL = Vertex::getX;
yL = Vertex::getY;


but this does not work as I get an error
'a value of type "int(vertex::*)()" cannot be assigned to an entity of type "int"

I presume this is because I am not getting the value from the object correctly.
closed account (D80DSL3A)
I tried to provide a hint with // assign values to xL and yL using itPrev
Have you not used iterators before? It's similar to a pointer to the list element.
1
2
xL = itPrev->X;
yL = itPrev->Y;
Sorry no, I've been learning for about 3 weeks.

Ive done some more work on it and realised that it wasn't going to work for the way I was writing the code.

I have now separated the Importing and sorting the values into the xL,yL etc, into separate functions.

my only issue now is that my syntax is wrong.
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
void getListValues(list<Vertex> Xlist)
{
list<Vertex>::iterator iter = Xlist.begin();
int xP=0, yP=0, xL=0, yL=0, xR=0, yR=0;
		while( iter != Xlist.end())
		{
			

			if(iter == Xlist.begin())
			{

				xP = Xlist[iter].getX();
				yP = Xlist[iter].getY();

				xL = Xlist.end().getX();
				yL = Xlist.end().getY();

				xR = Xlist[iter+1].getX();
				yR = Xlist[iter+1].getY();

			}
			
			if(iter != Xlist.begin() && iter != Xlist.end())
			{
	
				xP = Xlist[iter].getX();
				yP = Xlist[iter].getY();

				xL = Xlist[iter-1].getX();
				yL = Xlist[iter-1].getY();

				xR = Xlist[iter+1].getX();
				yR = Xlist[iter+1].getY();

			}

			double val = importanceMethod(xP, yP, xL, yL, xR, yR);
            iter->setF( val ); 
			++iter;
		}


		xP = Xlist[iter].getX();
		yP = Xlist[iter].getY();

		xL = Xlist[iter-1].getX();
		yL = Xlist.[iter-1].getY();

		xR = Xlist.begin().getX();
		yR = Xlist.begin().getY();


		double val = importanceMethod(xP, yP, xL, yL, xR, yR);
        iter->setF( val );
}
closed account (D80DSL3A)
OK, but pass that list by reference. Otherwise you're doing all that to a local copy of the list, not to the list you passed to the function.
ie.
void getListValues(list<Vertex>& Xlist)// note the & here

Yes, some of that code is outright illegal.
I have refined my approach to the problem, though it still seems a bit messy.
This code would be in your new getListValues() function.
1
2
3
4
5
6
7
8
// verify that the list has at least 3 elements. If not, we bail!
list<Vertex>::iterator itPrev, itCurr, itNext;
    itPrev = Xlist.begin();
    if( itPrev == Xlist.end() ) return;// empty list
    itCurr = itPrev; ++itCurr;
    if( itCurr == Xlist.end() ) return;// one element only
    itNext = itCurr; ++itNext;
    if( itNext == Xlist.end() ) return;// two elements only 

At this point itPrev, itCurr and itNext point to the 1st, 2nd and 3rd elements in the list. The following may get confusing...

If itNext were pointing to the last element then we would have iterators to all 3 elements needed to find F for the 1st element.
so with itNext = --Xlist.end();// last element
We find:
itPrev->F = importanceMethod( itPrev->X, itPrev->Y, itNext->X, itNext->Y, itCurr->X, itCurr->Y);// 1st element

Now, if itCurr were pointing to the 2nd to last element (the one before itNext presently) we could find F for the last element:
1
2
itCurr = itNext; --itCurr;// itCurr pt 2nd to last
    itNext->F = importanceMethod( itNext->X, itNext->Y, itCurr->X, itCurr->Y, itPrev->X, itPrev->Y);// Last element 

After that just iterate over all the middle elements while maintaining itPrev, itCurr and itNext so that
itCurr->F = importanceMethod( itCurr->X, itCurr->Y, itPrev->X, itPrev->Y, itNext->X, itNext->Y);

and you are DONE!
Last edited on
Sorry to go back to this but the code you gave me for importing code does not run, There is no error visible in the code but the program does not run.
1
2
3
4
5
6
7
8
9
10
int x;		
int y;

while ( Input >> x >> y )// failure aborts the while loop
	{		
               // the data in here is certainly valid
		Vertex v1( x, y);
		Xlist.push_back(v1);
	//	if (Input.eof()) break;// no need for this either
	}


I have been using this code which does run

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void import(list<Vertex> Xlist)
{
	int x;
	int y;
	ifstream Input;
	Input.open("swallow.txt");
	Input >> x >> y;

	while (!Input.eof())
	{
		Input >> x >> y;
		Vertex v1( x, y);
		Xlist.push_back(v1);
		cout << "X coordinate: " << x << " Y coordinate: " << y << endl;
	}
	Input.close();
	cout << "Import finished" << endl;
	
	
}


But this seems to produce an infinite loop that just prints the same X and Y coordinate infinitely.


X coordinate: -858993460 Y coordinate: -858993460
X coordinate: -858993460 Y coordinate: -858993460
X coordinate: -858993460 Y coordinate: -858993460
X coordinate: -858993460 Y coordinate: -858993460
X coordinate: -858993460 Y coordinate: -858993460
... and so on 
closed account (D80DSL3A)
Sorry about that setback I'm assuming that something went wrong with the file opening (wrong file name, missing file) or immediately after opening the file (stray character in the file, etc..).
I hope you get that worked out.

Actually, my code did exactly what one would want if the ifstream is corrupt, which is nothing (all bad input was ignored and no Vertex objects were created or inserted into Xlist).

Your code had a seizure.
Well the issue has been found, I put in an if(Input.good), to check if the input was corrupt and it turns out I had two text files of the same name, one with my coordinate data and one blank, but the only one I had added to the project was the blank one. I now feel really stupid as it imports correctly!

before failing the debug assertion but that's a different issue!

Thank you very much for your help!
closed account (D80DSL3A)
You're welcome for the help.

You have all the iterator usage and calculation of the F values working?
Good job!
I had thought that was the main issue in this thread.

I actually started my own thread (rare, for me) to see if I were missing any iterator manipulation tricks for use in your thread.
See here:
http://www.cplusplus.com/forum/beginner/130517/
Last edited on
Topic archived. No new replies allowed.