Delete duplicate elements from vector

In my software I get the coordinates (xyz) of points. I store this informations in a vector. So my function starts with this

1
2
3
4
5
6
7
8
  vector<vector<double> > matrix;

  rows = 2*lss.size();
  matrix.resize(rows);

  for(size_t i=0; i<rows; i++) {
      matrix[i].resize(columns);
  }

Then I fill the information into the vector and sort the vector.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int j=0;
for(size_t i = 0;i<lss.size();i++) {
    int k = j+1;

    matrix[j][0]=lss[i].v[0].x;
    matrix[j][1]=lss[i].v[0].y;
    matrix[j][2]=lss[i].v[0].z;
    matrix[k][0]=lss[i].v[1].x;
    matrix[k][1]=lss[i].v[1].y;
    matrix[k][2]=lss[i].v[1].z;

    j=j+2;
}
std::sort(matrix.begin(), matrix.end(), compare2);

After this I have to write the information of the vector to a file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int o=0;

for (size_t i=0; i<(lss.size()+1); i++) {
    int k=o+1;
			
    x2=xdiff+matrix[o][0];
    y2=ydiff+matrix[o][1];
    z2=zdiff+matrix[o][2];
    a2=xdiff+matrix[k][0];
    b2=ydiff+matrix[k][1];
    c2=zdiff+matrix[k][2];
			
    fprintf(f, "X8=%f, Y8=%f, Z8=%f \n", x2,y2,z2);
    fprintf(f, "X9=%f, Y9=%f, Z9=%f \n", a2,b2,c2);
			
    o=o+2;
}


My Problem now is that some points appear multiple times. So for further processing, it would be easier to delete the duplicates from the vector and to reduce the size of the vector.But since I'm new to the use of C ++, I can't find an appropriate method to achieve this. Does someone have a hint for me, how I could delete the duplicates in the vector, after it is sorted?
Last edited on
@Thomas1965 I tried the unique algorithmen but, everytime I start the program i get an erroro message.
Debug Assertion Failed! Expression: vector subscript out of range
.

My Code looks like this:
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
int j=0;
for(size_t i = 0;i<lss.size();i++) {
    int k = j+1;

    matrix[j][0]=lss[i].v[0].x;
    matrix[j][1]=lss[i].v[0].y;
    matrix[j][2]=lss[i].v[0].z;
    matrix[k][0]=lss[i].v[1].x;
    matrix[k][1]=lss[i].v[1].y;
    matrix[k][2]=lss[i].v[1].z;

    j=j+2;
}
std::sort(matrix.begin(), matrix.end(), compare2);
matrix.erase(std::unique(matrix.begin(), matrix.end()),matrix.end());
matrix.push_back(std::vector<double>(3, 0));//add a new element at the end to close contour

int p = matrix.size()-1;//get adress of last element
//copy first element to end to close contour
matrix[p][0]=matrix[0][0];
matrix[p][1]=matrix[0][1];
matrix[p][2]=matrix[0][2];

int o=0;
//print vector matrix
for (size_t i=0; i<((matrix.size())); i++) {
    int k=o+1;
			
    x2=xdiff+matrix[o][0];
    y2=ydiff+matrix[o][1];
    z2=zdiff+matrix[o][2];
    a2=xdiff+matrix[k][0];
    b2=ydiff+matrix[k][1];
    c2=zdiff+matrix[k][2];
			
    fprintf(f, "X8=%f, Y8=%f, Z8=%f \n", x2,y2,z2);
    fprintf(f, "X9=%f, Y9=%f, Z9=%f \n", a2,b2,c2);
			
    o=o+2;
}
Last edited on
What is your comparison predicate doing? Assuming it's taking two references to lists of vectors and doing some arbitrary axis-based sorting.

I think modelling coordinates this way is a bit painful - is there any reason you're not strongly modelling a Point/Coordinate? It looks like you're extracting the information from such an object then storing them in a matrix with implicit modelling.

Even if you want to store vector matrices, it's easy enough to write a Point/Coordinate class and a Matrix class composed of a number of them.

For the general case of removing duplicates from sorted vectors (with naive sorting and comparison), std::sort + std::unique should work just fine: https://ideone.com/v47Whq

However, when you talk about a vector with unique values often you might find what you actually want is a set: https://ideone.com/NQIVqY
You need to use the same comparison function as you did when you sorted.
 
matrix.erase(std::unique(matrix.begin(), matrix.end(), compare2),matrix.end());
@MrHutch: Sorry, but it's hard for me to understand what you are asking me for.
If you are asking what the compare2() function is doing, here's my code.
1
2
3
4
bool compare2(vector<double> const& s1, vector<double> const& s2)
{
	return atan2(s1[1],s1[0])<atan2(s2[1],s2[0]);
}

From this point i know the vector is sorted in the way I need it for further processing. I also had a look at the link for sorted vectors you send me, and from my experience I can't tell the difference between the code example and my code.
@Peter87 Okay I changed my code, now the erase() function seems to work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::sort(matrix.begin(), matrix.end(), compare2);

matrix.erase(std::unique(matrix.begin(), matrix.end(),compare2),matrix.end());

matrix.push_back(std::vector<double>(3, 0));

int p = matrix.size()-1;
		
matrix[p][0]=matrix[0][0];
matrix[p][1]=matrix[0][1];
matrix[p][2]=matrix[0][2];

for (size_t i=0; i<matrix.size(); i++) {
	x2=xdiff+matrix[i][0];
	y2=ydiff+matrix[i][1];
	z2=zdiff+matrix[i][2];
			
	fprintf(f, "X8=%f, Y8=%f, Z8=%f \n", x2,y2,z2);
}

The problem now is the compare2() function. It's deleting more elements than just the duplicates. My first guess would be to try a function like this
1
2
3
4
5
6
7
8
9
bool compare(vector<double> const& s1, vector<double> const& s2)
{
    if ( s1[0] != s2[0] )
    {
       return s1[0] > s2[0];
    }

	return s1[1] > s2[1];
}

What do you think about this function, could it work for my problem?
Last edited on
Thanks to all of you. I figured it out, how to solve the proble with the compare function.
Topic archived. No new replies allowed.